From 3edf4b30bdf1e369e9be177e934609e5ea73f02f Mon Sep 17 00:00:00 2001 From: Nick Vatamaniuc Date: Tue, 7 Jun 2022 16:37:52 -0400 Subject: Replace 3.x branch with a moved README marker file Use main and fdbmain from now on --- .credo.exs | 174 - .devcontainer/Dockerfile | 24 - .devcontainer/devcontainer.json | 19 - .formatter.exs | 9 - .github/ISSUE_TEMPLATE/bug_report.md | 36 - .github/ISSUE_TEMPLATE/enhancement.md | 27 - .github/ISSUE_TEMPLATE/rfc.md | 85 - .github/PULL_REQUEST_TEMPLATE.md | 35 - .gitignore | 132 - .mailmap | 13 - BUGS.md | 13 - COMMITTERS.md | 11 - CONTRIBUTING.md | 290 - CONTRIBUTORS.in | 97 - INSTALL.Unix.md | 264 - INSTALL.Windows.md | 21 - LICENSE | 2269 ------- Makefile | 511 -- Makefile.win | 450 -- NOTICE | 199 - README-DEV.rst | 256 - README.md | 3 + README.rst | 108 - bin/erlang-version.escript | 3 - build-aux/Jenkinsfile.full | 466 -- build-aux/Jenkinsfile.pr | 203 - build-aux/README.md | 131 - build-aux/couchdb-build-release.sh | 56 - build-aux/dist-error | 28 - build-aux/introspect | 73 - build-aux/logfile-uploader.py | 138 - build-aux/print-committerlist.sh | 68 - build-aux/show-test-results.py | 412 -- build-aux/sphinx-build | 34 - build-aux/sphinx-touch | 24 - config/config.exs | 30 - config/dev.exs | 1 - config/integration.exs | 9 - config/prod.exs | 1 - config/test.exs | 12 - configure | 360 -- configure.ps1 | 250 - dev/format_all.py | 35 - dev/format_check.py | 48 - dev/format_lib.py | 54 - dev/make_boot_script | 9 - dev/monitor_parent.erl | 41 - dev/pbkdf2.py | 201 - dev/remsh | 28 - dev/remsh-tls | 29 - dev/run | 862 --- dev/run.cmd | 15 - erlang_ls.config | 5 - make.cmd | 3 - mix.exs | 162 - mix.lock | 19 - rebar.config.script | 220 - rel/apps/config.config | 4 - rel/apps/couch_epi.config | 22 - rel/boot_dev_cluster.sh | 40 - rel/files/README | 18 - rel/files/couchdb.cmd.in | 37 - rel/files/couchdb.in | 52 - rel/files/eunit.config | 16 - rel/files/eunit.ini | 38 - rel/files/sys.config | 13 - rel/files/vm.args | 11 - rel/haproxy.cfg | 45 - rel/overlay/bin/remsh | 130 - rel/overlay/etc/default.d/README | 11 - rel/overlay/etc/default.ini | 749 --- rel/overlay/etc/local.d/README | 8 - rel/overlay/etc/local.ini | 95 - rel/overlay/etc/vm.args | 97 - rel/plugins/eunit_plugin.erl | 59 - rel/reltool.config | 152 - setup_eunit.template | 20 - share/server/60/escodegen.js | 1 - share/server/60/esprima.js | 6711 -------------------- share/server/60/rewrite_fun.js | 56 - share/server/coffee-script.js | 12 - share/server/dreyfus.js | 62 - share/server/filter.js | 46 - share/server/json2.js | 482 -- share/server/loop.js | 167 - share/server/mimeparse.js | 158 - share/server/render.js | 400 -- share/server/rewrite_fun.js | 20 - share/server/state.js | 31 - share/server/util.js | 157 - share/server/validate.js | 25 - share/server/views.js | 137 - src/chttpd/LICENSE | 202 - src/chttpd/include/chttpd.hrl | 28 - src/chttpd/include/chttpd_cors.hrl | 81 - src/chttpd/priv/stats_descriptions.cfg | 24 - src/chttpd/rebar.config | 2 - src/chttpd/src/chttpd.app.src | 33 - src/chttpd/src/chttpd.erl | 1622 ----- src/chttpd/src/chttpd_app.erl | 21 - src/chttpd/src/chttpd_auth.erl | 98 - src/chttpd/src/chttpd_auth_cache.erl | 267 - src/chttpd/src/chttpd_auth_request.erl | 156 - src/chttpd/src/chttpd_cors.erl | 414 -- src/chttpd/src/chttpd_db.erl | 2696 -------- src/chttpd/src/chttpd_epi.erl | 52 - src/chttpd/src/chttpd_external.erl | 218 - src/chttpd/src/chttpd_handlers.erl | 88 - src/chttpd/src/chttpd_httpd_handlers.erl | 46 - src/chttpd/src/chttpd_misc.erl | 328 - src/chttpd/src/chttpd_node.erl | 385 -- src/chttpd/src/chttpd_plugin.erl | 64 - src/chttpd/src/chttpd_prefer_header.erl | 61 - src/chttpd/src/chttpd_rewrite.erl | 553 -- src/chttpd/src/chttpd_show.erl | 331 - src/chttpd/src/chttpd_stats.erl | 96 - src/chttpd/src/chttpd_sup.erl | 178 - src/chttpd/src/chttpd_test_util.erl | 26 - src/chttpd/src/chttpd_util.erl | 112 - src/chttpd/src/chttpd_view.erl | 215 - src/chttpd/src/chttpd_xframe_options.erl | 90 - src/chttpd/test/eunit/chttpd_auth_tests.erl | 127 - src/chttpd/test/eunit/chttpd_cors_test.erl | 582 -- src/chttpd/test/eunit/chttpd_csp_tests.erl | 281 - .../test/eunit/chttpd_db_attachment_size_tests.erl | 203 - .../eunit/chttpd_db_bulk_get_multipart_test.erl | 366 -- src/chttpd/test/eunit/chttpd_db_bulk_get_test.erl | 372 -- src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl | 225 - src/chttpd/test/eunit/chttpd_db_test.erl | 618 -- src/chttpd/test/eunit/chttpd_dbs_info_test.erl | 334 - src/chttpd/test/eunit/chttpd_delayed_test.erl | 72 - src/chttpd/test/eunit/chttpd_error_info_tests.erl | 171 - src/chttpd/test/eunit/chttpd_external_test.erl | 122 - src/chttpd/test/eunit/chttpd_handlers_tests.erl | 88 - .../test/eunit/chttpd_open_revs_error_test.erl | 124 - src/chttpd/test/eunit/chttpd_plugin_tests.erl | 200 - .../test/eunit/chttpd_prefer_header_test.erl | 114 - src/chttpd/test/eunit/chttpd_purge_tests.erl | 491 -- src/chttpd/test/eunit/chttpd_revs_diff_tests.erl | 238 - src/chttpd/test/eunit/chttpd_security_tests.erl | 521 -- src/chttpd/test/eunit/chttpd_session_tests.erl | 81 - .../test/eunit/chttpd_socket_buffer_size_test.erl | 116 - src/chttpd/test/eunit/chttpd_test.hrl | 35 - src/chttpd/test/eunit/chttpd_util_test.erl | 114 - src/chttpd/test/eunit/chttpd_view_test.erl | 154 - src/chttpd/test/eunit/chttpd_welcome_test.erl | 101 - src/chttpd/test/eunit/chttpd_xframe_test.erl | 95 - src/couch/.gitignore | 23 - src/couch/LICENSE | 201 - src/couch/include/couch_db.hrl | 244 - src/couch/include/couch_eunit.hrl | 77 - src/couch/include/couch_eunit_proper.hrl | 33 - src/couch/include/couch_js_functions.hrl | 163 - .../priv/couch_ejson_compare/couch_ejson_compare.c | 603 -- src/couch/priv/couch_js/1.8.5/help.h | 79 - src/couch/priv/couch_js/1.8.5/main.c | 307 - src/couch/priv/couch_js/1.8.5/utf8.c | 297 - src/couch/priv/couch_js/1.8.5/utf8.h | 19 - src/couch/priv/couch_js/1.8.5/util.c | 296 - src/couch/priv/couch_js/1.8.5/util.h | 35 - src/couch/priv/couch_js/60/help.h | 79 - src/couch/priv/couch_js/60/main.cpp | 336 - src/couch/priv/couch_js/60/util.cpp | 355 -- src/couch/priv/couch_js/60/util.h | 38 - src/couch/priv/couch_js/68/help.h | 79 - src/couch/priv/couch_js/68/main.cpp | 337 - src/couch/priv/couch_js/68/util.cpp | 348 - src/couch/priv/couch_js/68/util.h | 41 - src/couch/priv/couch_js/86/help.h | 79 - src/couch/priv/couch_js/86/main.cpp | 344 - src/couch/priv/couch_js/86/util.cpp | 348 - src/couch/priv/couch_js/86/util.h | 41 - src/couch/priv/spawnkillable/couchspawnkillable.sh | 20 - .../priv/spawnkillable/couchspawnkillable_win.c | 145 - src/couch/priv/stats_descriptions.cfg | 332 - src/couch/rebar.config.script | 253 - src/couch/src/couch.app.src | 86 - src/couch/src/couch.erl | 62 - src/couch/src/couch_app.erl | 40 - src/couch/src/couch_att.erl | 970 --- src/couch/src/couch_auth_cache.erl | 172 - src/couch/src/couch_base32.erl | 156 - src/couch/src/couch_bt_engine.erl | 1229 ---- src/couch/src/couch_bt_engine.hrl | 27 - src/couch/src/couch_bt_engine_compactor.erl | 767 --- src/couch/src/couch_bt_engine_header.erl | 451 -- src/couch/src/couch_bt_engine_stream.erl | 60 - src/couch/src/couch_btree.erl | 1175 ---- src/couch/src/couch_changes.erl | 777 --- src/couch/src/couch_compress.erl | 95 - src/couch/src/couch_db.erl | 2374 ------- src/couch/src/couch_db_engine.erl | 1034 --- src/couch/src/couch_db_epi.erl | 51 - src/couch/src/couch_db_header.erl | 408 -- src/couch/src/couch_db_int.hrl | 76 - src/couch/src/couch_db_plugin.erl | 96 - src/couch/src/couch_db_split.erl | 523 -- src/couch/src/couch_db_updater.erl | 1029 --- src/couch/src/couch_debug.erl | 1067 ---- src/couch/src/couch_doc.erl | 588 -- src/couch/src/couch_ejson_compare.erl | 128 - src/couch/src/couch_ejson_size.erl | 92 - src/couch/src/couch_emsort.erl | 347 - src/couch/src/couch_event_sup.erl | 74 - src/couch/src/couch_file.erl | 956 --- src/couch/src/couch_flags.erl | 138 - src/couch/src/couch_flags_config.erl | 309 - src/couch/src/couch_hash.erl | 45 - src/couch/src/couch_hotp.erl | 31 - src/couch/src/couch_httpd.erl | 1492 ----- src/couch/src/couch_httpd_auth.erl | 697 -- src/couch/src/couch_httpd_db.erl | 1449 ----- src/couch/src/couch_httpd_handlers.erl | 21 - src/couch/src/couch_httpd_misc_handlers.erl | 313 - src/couch/src/couch_httpd_multipart.erl | 359 -- src/couch/src/couch_httpd_rewrite.erl | 555 -- src/couch/src/couch_httpd_vhost.erl | 457 -- src/couch/src/couch_io_logger.erl | 97 - src/couch/src/couch_key_tree.erl | 603 -- src/couch/src/couch_lru.erl | 68 - src/couch/src/couch_multidb_changes.erl | 859 --- src/couch/src/couch_native_process.erl | 488 -- src/couch/src/couch_os_process.erl | 274 - src/couch/src/couch_partition.erl | 155 - src/couch/src/couch_passwords.erl | 200 - src/couch/src/couch_primary_sup.erl | 34 - src/couch/src/couch_proc_manager.erl | 576 -- src/couch/src/couch_query_servers.erl | 934 --- src/couch/src/couch_rand.erl | 24 - src/couch/src/couch_secondary_sup.erl | 79 - src/couch/src/couch_server.erl | 1097 ---- src/couch/src/couch_server_int.hrl | 23 - src/couch/src/couch_stream.erl | 302 - src/couch/src/couch_sup.erl | 170 - src/couch/src/couch_task_status.erl | 154 - src/couch/src/couch_totp.erl | 24 - src/couch/src/couch_users_db.erl | 228 - src/couch/src/couch_util.erl | 817 --- src/couch/src/couch_uuids.erl | 188 - src/couch/src/couch_work_queue.erl | 174 - src/couch/src/test_request.erl | 110 - src/couch/src/test_util.erl | 429 -- src/couch/test/eunit/chttpd_endpoints_tests.erl | 108 - src/couch/test/eunit/couch_auth_cache_tests.erl | 382 -- src/couch/test/eunit/couch_base32_tests.erl | 28 - .../test/eunit/couch_bt_engine_compactor_ev.erl | 101 - .../eunit/couch_bt_engine_compactor_ev_tests.erl | 336 - .../test/eunit/couch_bt_engine_compactor_tests.erl | 124 - src/couch/test/eunit/couch_bt_engine_tests.erl | 18 - .../test/eunit/couch_bt_engine_upgrade_tests.erl | 255 - src/couch/test/eunit/couch_btree_tests.erl | 693 -- src/couch/test/eunit/couch_changes_tests.erl | 1093 ---- src/couch/test/eunit/couch_db_doc_tests.erl | 117 - src/couch/test/eunit/couch_db_mpr_tests.erl | 127 - src/couch/test/eunit/couch_db_plugin_tests.erl | 233 - .../test/eunit/couch_db_props_upgrade_tests.erl | 77 - src/couch/test/eunit/couch_db_split_tests.erl | 358 -- src/couch/test/eunit/couch_db_tests.erl | 212 - src/couch/test/eunit/couch_doc_json_tests.erl | 526 -- src/couch/test/eunit/couch_doc_tests.erl | 179 - src/couch/test/eunit/couch_ejson_compare_tests.erl | 289 - src/couch/test/eunit/couch_ejson_size_tests.erl | 99 - src/couch/test/eunit/couch_etag_tests.erl | 31 - src/couch/test/eunit/couch_file_tests.erl | 553 -- src/couch/test/eunit/couch_flags_config_tests.erl | 147 - src/couch/test/eunit/couch_flags_tests.erl | 158 - src/couch/test/eunit/couch_hotp_tests.erl | 28 - src/couch/test/eunit/couch_index_tests.erl | 273 - src/couch/test/eunit/couch_js_tests.erl | 200 - src/couch/test/eunit/couch_key_tree_prop_tests.erl | 531 -- src/couch/test/eunit/couch_key_tree_tests.erl | 576 -- src/couch/test/eunit/couch_passwords_tests.erl | 65 - src/couch/test/eunit/couch_query_servers_tests.erl | 154 - src/couch/test/eunit/couch_server_tests.erl | 290 - src/couch/test/eunit/couch_stream_tests.erl | 128 - src/couch/test/eunit/couch_task_status_tests.erl | 243 - src/couch/test/eunit/couch_totp_tests.erl | 55 - src/couch/test/eunit/couch_util_tests.erl | 152 - src/couch/test/eunit/couch_uuids_tests.erl | 109 - src/couch/test/eunit/couch_work_queue_tests.erl | 416 -- src/couch/test/eunit/couchdb_attachments_tests.erl | 851 --- src/couch/test/eunit/couchdb_auth_tests.erl | 132 - .../test/eunit/couchdb_cookie_domain_tests.erl | 88 - src/couch/test/eunit/couchdb_cors_tests.erl | 431 -- src/couch/test/eunit/couchdb_db_tests.erl | 88 - src/couch/test/eunit/couchdb_design_doc_tests.erl | 99 - .../test/eunit/couchdb_file_compression_tests.erl | 251 - .../test/eunit/couchdb_location_header_tests.erl | 83 - src/couch/test/eunit/couchdb_mrview_cors_tests.erl | 142 - src/couch/test/eunit/couchdb_mrview_tests.erl | 272 - src/couch/test/eunit/couchdb_os_proc_pool.erl | 390 -- .../test/eunit/couchdb_update_conflicts_tests.erl | 348 - src/couch/test/eunit/couchdb_vhosts_tests.erl | 346 - src/couch/test/eunit/couchdb_views_tests.erl | 1125 ---- .../fixtures/15a5cb17365a99cd9ddc7327c82bbd0d.view | Bin 12388 -> 0 bytes .../fixtures/1f2c24bc334d701c2048f85e7438eef1.view | Bin 4230 -> 0 bytes .../fixtures/6cf2c2f766f87b618edf6630b00f8736.view | Bin 8310 -> 0 bytes src/couch/test/eunit/fixtures/colltest1.couch | Bin 24768 -> 0 bytes .../test/eunit/fixtures/couch_stats_aggregates.cfg | 19 - .../test/eunit/fixtures/couch_stats_aggregates.ini | 20 - src/couch/test/eunit/fixtures/db321.couch | Bin 28864 -> 0 bytes .../test/eunit/fixtures/db_non_partitioned.couch | Bin 12479 -> 0 bytes .../eunit/fixtures/db_v6_with_1_purge_req.couch | Bin 12470 -> 0 bytes .../db_v6_with_1_purge_req_for_2_docs.couch | Bin 16557 -> 0 bytes .../eunit/fixtures/db_v6_with_2_purge_req.couch | Bin 16566 -> 0 bytes .../eunit/fixtures/db_v6_without_purge_req.couch | Bin 61644 -> 0 bytes .../eunit/fixtures/db_v7_with_1_purge_req.couch | Bin 16617 -> 0 bytes .../db_v7_with_1_purge_req_for_2_docs.couch | Bin 20705 -> 0 bytes .../eunit/fixtures/db_v7_with_2_purge_req.couch | Bin 20713 -> 0 bytes .../eunit/fixtures/db_v7_without_purge_req.couch | Bin 65781 -> 0 bytes src/couch/test/eunit/fixtures/logo.png | Bin 3010 -> 0 bytes src/couch/test/eunit/fixtures/multipart.http | 13 - .../test/eunit/fixtures/os_daemon_bad_perm.sh | 17 - .../test/eunit/fixtures/os_daemon_can_reboot.sh | 15 - .../test/eunit/fixtures/os_daemon_configer.escript | 97 - .../test/eunit/fixtures/os_daemon_die_on_boot.sh | 15 - .../test/eunit/fixtures/os_daemon_die_quickly.sh | 15 - .../test/eunit/fixtures/os_daemon_looper.escript | 26 - src/couch/test/eunit/fixtures/test.couch | Bin 28878 -> 0 bytes src/couch/test/eunit/global_changes_tests.erl | 164 - src/couch/test/eunit/json_stream_parse_tests.erl | 157 - src/couch/test/eunit/test_web.erl | 114 - src/couch/test/exunit/couch_compress_tests.exs | 113 - src/couch/test/exunit/fabric_test.exs | 101 - src/couch/test/exunit/same_site_cookie_tests.exs | 44 - src/couch/test/exunit/test_helper.exs | 2 - src/couch_dist/LICENSE | 177 - src/couch_dist/rebar.config | 2 - src/couch_dist/src/couch_dist.app.src | 19 - src/couch_dist/src/couch_dist.erl | 149 - src/couch_dist/test/eunit/couch_dist_tests.erl | 95 - src/couch_epi/.gitignore | 4 - src/couch_epi/LICENSE | 203 - src/couch_epi/README.md | 166 - src/couch_epi/rebar.config | 7 - src/couch_epi/src/couch_epi.app.src.script | 28 - src/couch_epi/src/couch_epi.erl | 199 - src/couch_epi/src/couch_epi.hrl | 15 - src/couch_epi/src/couch_epi_app.erl | 23 - src/couch_epi/src/couch_epi_codechange_monitor.erl | 69 - src/couch_epi/src/couch_epi_codegen.erl | 94 - src/couch_epi/src/couch_epi_data.erl | 120 - src/couch_epi/src/couch_epi_data_gen.erl | 307 - src/couch_epi/src/couch_epi_functions.erl | 53 - src/couch_epi/src/couch_epi_functions_gen.erl | 492 -- src/couch_epi/src/couch_epi_module_keeper.erl | 174 - src/couch_epi/src/couch_epi_plugin.erl | 395 -- src/couch_epi/src/couch_epi_sup.erl | 163 - src/couch_epi/src/couch_epi_util.erl | 29 - src/couch_epi/test/eunit/couch_epi_basic_test.erl | 167 - src/couch_epi/test/eunit/couch_epi_tests.erl | 724 --- src/couch_epi/test/eunit/fixtures/app_data1.cfg | 4 - src/couch_epi/test/eunit/fixtures/app_data2.cfg | 8 - src/couch_event/.gitignore | 2 - src/couch_event/LICENSE | 202 - src/couch_event/README.md | 3 - src/couch_event/rebar.config | 1 - src/couch_event/src/couch_event.app.src | 22 - src/couch_event/src/couch_event.erl | 56 - src/couch_event/src/couch_event_app.erl | 25 - src/couch_event/src/couch_event_int.hrl | 19 - src/couch_event/src/couch_event_listener.erl | 218 - src/couch_event/src/couch_event_listener_mfa.erl | 96 - src/couch_event/src/couch_event_os_listener.erl | 67 - src/couch_event/src/couch_event_server.erl | 150 - src/couch_event/src/couch_event_sup2.erl | 36 - src/couch_index/.gitignore | 3 - src/couch_index/LICENSE | 202 - src/couch_index/rebar.config | 2 - src/couch_index/src/couch_index.app.src | 19 - src/couch_index/src/couch_index.erl | 618 -- src/couch_index/src/couch_index_app.erl | 21 - src/couch_index/src/couch_index_compactor.erl | 122 - src/couch_index/src/couch_index_debug.erl | 171 - src/couch_index/src/couch_index_epi.erl | 50 - src/couch_index/src/couch_index_plugin.erl | 51 - .../src/couch_index_plugin_couch_db.erl | 24 - src/couch_index/src/couch_index_server.erl | 396 -- src/couch_index/src/couch_index_sup.erl | 23 - src/couch_index/src/couch_index_updater.erl | 231 - src/couch_index/src/couch_index_util.erl | 74 - .../test/eunit/couch_index_compaction_tests.erl | 123 - .../test/eunit/couch_index_ddoc_updated_tests.erl | 177 - src/couch_log/.gitignore | 3 - src/couch_log/LICENSE | 202 - src/couch_log/include/couch_log.hrl | 22 - src/couch_log/priv/stats_descriptions.cfg | 48 - src/couch_log/rebar.config | 2 - src/couch_log/src/couch_log.app.src | 19 - src/couch_log/src/couch_log.erl | 65 - src/couch_log/src/couch_log_app.erl | 23 - src/couch_log/src/couch_log_config.erl | 120 - src/couch_log/src/couch_log_config_dyn.erl | 28 - src/couch_log/src/couch_log_error_logger_h.erl | 48 - src/couch_log/src/couch_log_formatter.erl | 438 -- src/couch_log/src/couch_log_monitor.erl | 69 - src/couch_log/src/couch_log_server.erl | 92 - src/couch_log/src/couch_log_sup.erl | 93 - src/couch_log/src/couch_log_trunc_io.erl | 1105 ---- src/couch_log/src/couch_log_trunc_io_fmt.erl | 593 -- src/couch_log/src/couch_log_util.erl | 147 - src/couch_log/src/couch_log_writer.erl | 73 - src/couch_log/src/couch_log_writer_file.erl | 131 - src/couch_log/src/couch_log_writer_journald.erl | 63 - src/couch_log/src/couch_log_writer_stderr.erl | 49 - src/couch_log/src/couch_log_writer_syslog.erl | 201 - .../test/eunit/couch_log_config_listener_test.erl | 79 - src/couch_log/test/eunit/couch_log_config_test.erl | 170 - .../test/eunit/couch_log_error_logger_h_test.erl | 36 - .../test/eunit/couch_log_formatter_test.erl | 966 --- .../test/eunit/couch_log_monitor_test.erl | 56 - src/couch_log/test/eunit/couch_log_server_test.erl | 110 - src/couch_log/test/eunit/couch_log_test.erl | 76 - src/couch_log/test/eunit/couch_log_test_util.erl | 170 - .../test/eunit/couch_log_trunc_io_fmt_test.erl | 91 - src/couch_log/test/eunit/couch_log_util_test.erl | 91 - src/couch_log/test/eunit/couch_log_writer_ets.erl | 44 - .../test/eunit/couch_log_writer_file_test.erl | 155 - .../test/eunit/couch_log_writer_stderr_test.erl | 49 - .../test/eunit/couch_log_writer_syslog_test.erl | 144 - src/couch_log/test/eunit/couch_log_writer_test.erl | 46 - src/couch_mrview/LICENSE | 202 - src/couch_mrview/include/couch_mrview.hrl | 112 - src/couch_mrview/priv/stats_descriptions.cfg | 24 - src/couch_mrview/rebar.config | 2 - src/couch_mrview/src/couch_mrview.app.src | 18 - src/couch_mrview/src/couch_mrview.erl | 748 --- src/couch_mrview/src/couch_mrview_cleanup.erl | 68 - src/couch_mrview/src/couch_mrview_compactor.erl | 317 - src/couch_mrview/src/couch_mrview_debug.erl | 50 - src/couch_mrview/src/couch_mrview_http.erl | 674 -- src/couch_mrview/src/couch_mrview_index.erl | 362 -- src/couch_mrview/src/couch_mrview_show.erl | 515 -- src/couch_mrview/src/couch_mrview_test_util.erl | 136 - .../src/couch_mrview_update_notifier.erl | 51 - src/couch_mrview/src/couch_mrview_updater.erl | 383 -- src/couch_mrview/src/couch_mrview_util.erl | 1292 ---- .../test/eunit/couch_mrview_all_docs_tests.erl | 145 - .../test/eunit/couch_mrview_collation_tests.erl | 236 - .../test/eunit/couch_mrview_compact_tests.erl | 130 - .../test/eunit/couch_mrview_ddoc_updated_tests.erl | 157 - .../eunit/couch_mrview_ddoc_validation_tests.erl | 557 -- .../test/eunit/couch_mrview_design_docs_tests.erl | 144 - .../test/eunit/couch_mrview_http_tests.erl | 37 - .../test/eunit/couch_mrview_index_info_tests.erl | 99 - .../test/eunit/couch_mrview_local_docs_tests.erl | 158 - .../test/eunit/couch_mrview_map_views_tests.erl | 152 - .../eunit/couch_mrview_purge_docs_fabric_tests.erl | 314 - .../test/eunit/couch_mrview_purge_docs_tests.erl | 607 -- .../test/eunit/couch_mrview_red_views_tests.erl | 97 - .../test/eunit/couch_mrview_util_tests.erl | 37 - src/couch_peruser/.gitignore | 9 - src/couch_peruser/LICENSE | 202 - src/couch_peruser/README.md | 34 - src/couch_peruser/src/couch_peruser.app.src | 20 - src/couch_peruser/src/couch_peruser.erl | 505 -- src/couch_peruser/src/couch_peruser_app.erl | 23 - src/couch_peruser/src/couch_peruser_sup.erl | 26 - .../test/eunit/couch_peruser_test.erl | 569 -- src/couch_plugins/LICENSE | 202 - src/couch_plugins/Makefile.am | 40 - src/couch_plugins/README.md | 159 - src/couch_plugins/src/couch_plugins.app.src | 22 - src/couch_plugins/src/couch_plugins.erl | 322 - src/couch_plugins/src/couch_plugins_httpd.erl | 69 - src/couch_prometheus/src/couch_prometheus.app.src | 20 - src/couch_prometheus/src/couch_prometheus.hrl | 15 - src/couch_prometheus/src/couch_prometheus_app.erl | 23 - src/couch_prometheus/src/couch_prometheus_http.erl | 112 - .../src/couch_prometheus_server.erl | 189 - src/couch_prometheus/src/couch_prometheus_sup.erl | 40 - src/couch_prometheus/src/couch_prometheus_util.erl | 169 - .../test/eunit/couch_prometheus_e2e_tests.erl | 151 - .../test/eunit/couch_prometheus_util_tests.erl | 75 - src/couch_pse_tests/src/couch_pse_tests.app.src | 20 - src/couch_pse_tests/src/cpse_gather.erl | 95 - src/couch_pse_tests/src/cpse_test_attachments.erl | 98 - src/couch_pse_tests/src/cpse_test_compaction.erl | 331 - .../src/cpse_test_copy_purge_infos.erl | 88 - src/couch_pse_tests/src/cpse_test_fold_changes.erl | 182 - src/couch_pse_tests/src/cpse_test_fold_docs.erl | 414 -- .../src/cpse_test_fold_purge_infos.erl | 179 - .../src/cpse_test_get_set_props.erl | 90 - .../src/cpse_test_open_close_delete.erl | 70 - .../src/cpse_test_purge_bad_checkpoints.erl | 83 - src/couch_pse_tests/src/cpse_test_purge_docs.erl | 453 -- .../src/cpse_test_purge_replication.erl | 206 - src/couch_pse_tests/src/cpse_test_purge_seqs.erl | 125 - .../src/cpse_test_read_write_docs.erl | 303 - src/couch_pse_tests/src/cpse_test_ref_counting.erl | 105 - src/couch_pse_tests/src/cpse_util.erl | 667 -- src/couch_replicator/.gitignore | 4 - src/couch_replicator/LICENSE | 202 - src/couch_replicator/README.md | 285 - .../include/couch_replicator_api_wrap.hrl | 31 - src/couch_replicator/priv/stats_descriptions.cfg | 152 - src/couch_replicator/src/couch_replicator.app.src | 37 - src/couch_replicator/src/couch_replicator.erl | 419 -- src/couch_replicator/src/couch_replicator.hrl | 59 - .../src/couch_replicator_api_wrap.erl | 1057 --- src/couch_replicator/src/couch_replicator_app.erl | 17 - src/couch_replicator/src/couch_replicator_auth.erl | 95 - .../src/couch_replicator_auth_noop.erl | 44 - .../src/couch_replicator_auth_session.erl | 719 --- .../src/couch_replicator_changes_reader.erl | 158 - .../src/couch_replicator_clustering.erl | 269 - .../src/couch_replicator_connection.erl | 281 - .../src/couch_replicator_db_changes.erl | 103 - .../src/couch_replicator_doc_processor.erl | 934 --- .../src/couch_replicator_doc_processor_worker.erl | 295 - src/couch_replicator/src/couch_replicator_docs.erl | 952 --- .../src/couch_replicator_fabric.erl | 158 - .../src/couch_replicator_fabric_rpc.erl | 97 - .../src/couch_replicator_filters.erl | 220 - .../src/couch_replicator_httpc.erl | 538 -- .../src/couch_replicator_httpc_pool.erl | 216 - .../src/couch_replicator_httpd.erl | 190 - .../src/couch_replicator_httpd_util.erl | 201 - src/couch_replicator/src/couch_replicator_ids.erl | 282 - .../src/couch_replicator_job_sup.erl | 34 - .../src/couch_replicator_js_functions.hrl | 177 - .../src/couch_replicator_notifier.erl | 60 - .../src/couch_replicator_rate_limiter.erl | 239 - .../src/couch_replicator_rate_limiter_tables.erl | 56 - .../src/couch_replicator_scheduler.erl | 1690 ----- .../src/couch_replicator_scheduler_job.erl | 1182 ---- .../src/couch_replicator_scheduler_sup.erl | 59 - .../src/couch_replicator_share.erl | 762 --- .../src/couch_replicator_stats.erl | 87 - src/couch_replicator/src/couch_replicator_sup.erl | 40 - .../src/couch_replicator_utils.erl | 572 -- .../src/couch_replicator_worker.erl | 546 -- src/couch_replicator/src/json_stream_parse.erl | 425 -- .../couch_replicator_attachments_too_large.erl | 99 - .../test/eunit/couch_replicator_compact_tests.erl | 523 -- .../eunit/couch_replicator_connection_tests.erl | 237 - ...replicator_create_target_with_options_tests.erl | 144 - .../couch_replicator_error_reporting_tests.erl | 260 - .../test/eunit/couch_replicator_filtered_tests.erl | 262 - .../eunit/couch_replicator_httpc_pool_tests.erl | 178 - .../eunit/couch_replicator_id_too_long_tests.erl | 86 - .../eunit/couch_replicator_large_atts_tests.erl | 127 - .../eunit/couch_replicator_many_leaves_tests.erl | 229 - .../eunit/couch_replicator_missing_stubs_tests.erl | 159 - .../test/eunit/couch_replicator_proxy_tests.erl | 123 - .../eunit/couch_replicator_rate_limiter_tests.erl | 79 - ...ch_replicator_retain_stats_between_job_runs.erl | 287 - .../test/eunit/couch_replicator_selector_tests.erl | 122 - ...ch_replicator_small_max_request_size_target.erl | 184 - .../test/eunit/couch_replicator_test.hrl | 35 - .../test/eunit/couch_replicator_test_helper.erl | 147 - .../couch_replicator_use_checkpoints_tests.erl | 201 - src/couch_stats/.gitignore | 6 - src/couch_stats/LICENSE | 201 - src/couch_stats/README.md | 29 - src/couch_stats/priv/sample_descriptions.cfg | 15 - src/couch_stats/src/couch_stats.app.src | 20 - src/couch_stats/src/couch_stats.erl | 130 - src/couch_stats/src/couch_stats.hrl | 14 - src/couch_stats/src/couch_stats_aggregator.erl | 162 - src/couch_stats/src/couch_stats_app.erl | 23 - src/couch_stats/src/couch_stats_httpd.erl | 115 - .../src/couch_stats_process_tracker.erl | 80 - src/couch_stats/src/couch_stats_sup.erl | 34 - src/couch_tests/.gitignore | 6 - src/couch_tests/include/couch_tests.hrl | 28 - src/couch_tests/rebar.config | 20 - src/couch_tests/setups/couch_epi_dispatch.erl | 98 - src/couch_tests/src/couch_tests.app.src | 18 - src/couch_tests/src/couch_tests.erl | 233 - src/couch_tests/src/couch_tests_combinatorics.erl | 136 - src/couch_tests/test/couch_tests_app_tests.erl | 117 - src/custodian/README | 8 - src/custodian/rebar.config.script | 35 - src/custodian/src/custodian.app.src.script | 48 - src/custodian/src/custodian.erl | 21 - src/custodian/src/custodian_app.erl | 28 - src/custodian/src/custodian_db_checker.erl | 139 - src/custodian/src/custodian_monitor.erl | 26 - src/custodian/src/custodian_noop_monitor.erl | 30 - src/custodian/src/custodian_server.erl | 244 - src/custodian/src/custodian_sup.erl | 45 - src/custodian/src/custodian_util.erl | 284 - src/ddoc_cache/LICENSE | 202 - src/ddoc_cache/README.md | 4 - src/ddoc_cache/priv/stats_descriptions.cfg | 12 - src/ddoc_cache/src/ddoc_cache.app.src | 31 - src/ddoc_cache/src/ddoc_cache.erl | 53 - src/ddoc_cache/src/ddoc_cache.hrl | 40 - src/ddoc_cache/src/ddoc_cache_app.erl | 22 - src/ddoc_cache/src/ddoc_cache_entry.erl | 327 - src/ddoc_cache/src/ddoc_cache_entry_custom.erl | 32 - src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl | 39 - src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl | 39 - .../src/ddoc_cache_entry_validation_funs.erl | 42 - src/ddoc_cache/src/ddoc_cache_lru.erl | 337 - src/ddoc_cache/src/ddoc_cache_sup.erl | 35 - src/ddoc_cache/src/ddoc_cache_value.erl | 24 - .../test/eunit/ddoc_cache_basic_test.erl | 159 - .../test/eunit/ddoc_cache_coverage_test.erl | 71 - .../test/eunit/ddoc_cache_disabled_test.erl | 56 - .../test/eunit/ddoc_cache_entry_test.erl | 156 - src/ddoc_cache/test/eunit/ddoc_cache_ev.erl | 20 - .../test/eunit/ddoc_cache_eviction_test.erl | 74 - src/ddoc_cache/test/eunit/ddoc_cache_lru_test.erl | 245 - .../test/eunit/ddoc_cache_no_cache_test.erl | 81 - .../test/eunit/ddoc_cache_open_error_test.erl | 41 - src/ddoc_cache/test/eunit/ddoc_cache_open_test.erl | 102 - .../test/eunit/ddoc_cache_refresh_test.erl | 150 - .../test/eunit/ddoc_cache_remove_test.erl | 221 - src/ddoc_cache/test/eunit/ddoc_cache_test.hrl | 26 - src/ddoc_cache/test/eunit/ddoc_cache_tutil.erl | 110 - src/dreyfus/.gitignore | 4 - src/dreyfus/LICENSE.txt | 202 - src/dreyfus/README.md | 78 - src/dreyfus/include/dreyfus.hrl | 74 - src/dreyfus/priv/stats_descriptions.cfg | 65 - src/dreyfus/src/clouseau_rpc.erl | 108 - src/dreyfus/src/dreyfus.app.src | 22 - src/dreyfus/src/dreyfus.erl | 31 - src/dreyfus/src/dreyfus_app.erl | 23 - src/dreyfus/src/dreyfus_bookmark.erl | 88 - src/dreyfus/src/dreyfus_config.erl | 16 - src/dreyfus/src/dreyfus_epi.erl | 47 - src/dreyfus/src/dreyfus_fabric.erl | 270 - src/dreyfus/src/dreyfus_fabric_cleanup.erl | 105 - src/dreyfus/src/dreyfus_fabric_group1.erl | 153 - src/dreyfus/src/dreyfus_fabric_group2.erl | 185 - src/dreyfus/src/dreyfus_fabric_info.erl | 112 - src/dreyfus/src/dreyfus_fabric_search.erl | 334 - src/dreyfus/src/dreyfus_httpd.erl | 709 --- src/dreyfus/src/dreyfus_httpd_handlers.erl | 28 - src/dreyfus/src/dreyfus_index.erl | 432 -- src/dreyfus/src/dreyfus_index_manager.erl | 160 - src/dreyfus/src/dreyfus_index_updater.erl | 184 - src/dreyfus/src/dreyfus_plugin_couch_db.erl | 24 - src/dreyfus/src/dreyfus_rpc.erl | 134 - src/dreyfus/src/dreyfus_sup.erl | 30 - src/dreyfus/src/dreyfus_util.erl | 486 -- src/dreyfus/test/dreyfus_blacklist_await_test.erl | 86 - .../test/dreyfus_blacklist_request_test.erl | 164 - src/dreyfus/test/dreyfus_config_test.erl | 74 - src/dreyfus/test/dreyfus_purge_test.erl | 1118 ---- src/dreyfus/test/dreyfus_test_util.erl | 15 - src/dreyfus/test/elixir/mix.exs | 30 - src/dreyfus/test/elixir/mix.lock | 5 - src/dreyfus/test/elixir/run | 4 - .../test/elixir/test/partition_search_test.exs | 247 - src/dreyfus/test/elixir/test/search_test.exs | 226 - src/dreyfus/test/elixir/test/test_helper.exs | 4 - src/fabric/LICENSE | 202 - src/fabric/README.md | 18 - src/fabric/include/fabric.hrl | 46 - src/fabric/priv/stats_descriptions.cfg | 28 - src/fabric/rebar.config | 14 - src/fabric/src/fabric.app.src | 27 - src/fabric/src/fabric.erl | 840 --- src/fabric/src/fabric_db_create.erl | 237 - src/fabric/src/fabric_db_delete.erl | 95 - src/fabric/src/fabric_db_doc_count.erl | 59 - src/fabric/src/fabric_db_info.erl | 191 - src/fabric/src/fabric_db_meta.erl | 200 - src/fabric/src/fabric_db_partition_info.erl | 148 - src/fabric/src/fabric_db_update_listener.erl | 183 - src/fabric/src/fabric_db_uuids.erl | 64 - src/fabric/src/fabric_design_doc_count.erl | 59 - src/fabric/src/fabric_dict.erl | 60 - src/fabric/src/fabric_doc_atts.erl | 177 - src/fabric/src/fabric_doc_missing_revs.erl | 116 - src/fabric/src/fabric_doc_open.erl | 611 -- src/fabric/src/fabric_doc_open_revs.erl | 766 --- src/fabric/src/fabric_doc_purge.erl | 591 -- src/fabric/src/fabric_doc_update.erl | 762 --- src/fabric/src/fabric_group_info.erl | 164 - src/fabric/src/fabric_ring.erl | 560 -- src/fabric/src/fabric_rpc.erl | 706 -- src/fabric/src/fabric_streams.erl | 283 - src/fabric/src/fabric_util.erl | 477 -- src/fabric/src/fabric_view.erl | 561 -- src/fabric/src/fabric_view_all_docs.erl | 361 -- src/fabric/src/fabric_view_changes.erl | 1042 --- src/fabric/src/fabric_view_map.erl | 292 - src/fabric/src/fabric_view_reduce.erl | 181 - src/fabric/test/eunit/fabric_db_create_tests.erl | 49 - src/fabric/test/eunit/fabric_db_info_tests.erl | 62 - src/fabric/test/eunit/fabric_db_uuids_tests.erl | 55 - .../test/eunit/fabric_moved_shards_seq_tests.erl | 111 - src/fabric/test/eunit/fabric_rpc_purge_tests.erl | 288 - src/fabric/test/eunit/fabric_rpc_tests.erl | 187 - src/fabric/test/eunit/fabric_tests.erl | 59 - src/global_changes/.gitignore | 2 - src/global_changes/LICENSE | 203 - src/global_changes/README.md | 27 - src/global_changes/priv/stats_descriptions.cfg | 20 - src/global_changes/src/global_changes.app.src | 32 - src/global_changes/src/global_changes_app.erl | 25 - src/global_changes/src/global_changes_epi.erl | 50 - src/global_changes/src/global_changes_httpd.erl | 298 - .../src/global_changes_httpd_handlers.erl | 22 - src/global_changes/src/global_changes_listener.erl | 175 - src/global_changes/src/global_changes_plugin.erl | 39 - src/global_changes/src/global_changes_server.erl | 227 - src/global_changes/src/global_changes_sup.erl | 82 - src/global_changes/src/global_changes_util.erl | 25 - .../test/eunit/global_changes_hooks_tests.erl | 164 - src/ioq/.gitignore | 2 - src/ioq/src/ioq.app.src | 21 - src/ioq/src/ioq.erl | 208 - src/ioq/src/ioq_app.erl | 21 - src/ioq/src/ioq_sup.erl | 24 - src/jwtf/.gitignore | 4 - src/jwtf/LICENSE | 176 - src/jwtf/README.md | 18 - src/jwtf/rebar.config | 2 - src/jwtf/src/jwtf.app.src | 32 - src/jwtf/src/jwtf.erl | 414 -- src/jwtf/src/jwtf_app.erl | 28 - src/jwtf/src/jwtf_keystore.erl | 152 - src/jwtf/src/jwtf_sup.erl | 38 - src/jwtf/test/jwtf_keystore_tests.erl | 61 - src/jwtf/test/jwtf_tests.erl | 425 -- src/ken/README.md | 12 - src/ken/rebar.config.script | 28 - src/ken/src/ken.app.src.script | 38 - src/ken/src/ken.erl | 29 - src/ken/src/ken_app.erl | 28 - src/ken/src/ken_event_handler.erl | 55 - src/ken/src/ken_server.erl | 605 -- src/ken/src/ken_sup.erl | 32 - src/ken/test/config.ini | 2 - src/ken/test/ken_server_test.erl | 90 - src/mango/.gitignore | 5 - src/mango/LICENSE.txt | 202 - src/mango/README.md | 372 -- src/mango/TODO.md | 9 - src/mango/rebar.config.script | 26 - src/mango/requirements.txt | 4 - src/mango/src/mango.app.src | 26 - src/mango/src/mango.hrl | 13 - src/mango/src/mango_app.erl | 21 - src/mango/src/mango_crud.erl | 171 - src/mango/src/mango_cursor.erl | 253 - src/mango/src/mango_cursor.hrl | 31 - src/mango/src/mango_cursor_special.erl | 65 - src/mango/src/mango_cursor_text.erl | 334 - src/mango/src/mango_cursor_view.erl | 504 -- src/mango/src/mango_doc.erl | 543 -- src/mango/src/mango_epi.erl | 48 - src/mango/src/mango_error.erl | 380 -- src/mango/src/mango_execution_stats.erl | 86 - src/mango/src/mango_execution_stats.hrl | 20 - src/mango/src/mango_fields.erl | 55 - src/mango/src/mango_httpd.erl | 336 - src/mango/src/mango_httpd_handlers.erl | 24 - src/mango/src/mango_idx.erl | 513 -- src/mango/src/mango_idx.hrl | 21 - src/mango/src/mango_idx_special.erl | 98 - src/mango/src/mango_idx_text.erl | 459 -- src/mango/src/mango_idx_view.erl | 523 -- src/mango/src/mango_idx_view.hrl | 13 - src/mango/src/mango_json.erl | 112 - src/mango/src/mango_json_bookmark.erl | 70 - src/mango/src/mango_native_proc.erl | 346 - src/mango/src/mango_opts.erl | 360 -- src/mango/src/mango_selector.erl | 985 --- src/mango/src/mango_selector_text.erl | 423 -- src/mango/src/mango_sort.erl | 68 - src/mango/src/mango_sup.erl | 23 - src/mango/src/mango_util.erl | 405 -- src/mango/test/01-index-crud-test.py | 384 -- src/mango/test/02-basic-find-test.py | 302 - src/mango/test/03-operator-test.py | 203 - src/mango/test/04-key-tests.py | 158 - src/mango/test/05-index-selection-test.py | 336 - src/mango/test/06-basic-text-test.py | 602 -- src/mango/test/06-text-default-field-test.py | 67 - src/mango/test/07-text-custom-field-list-test.py | 209 - src/mango/test/08-text-limit-test.py | 135 - src/mango/test/09-text-sort-test.py | 115 - .../test/10-disable-array-length-field-test.py | 44 - src/mango/test/11-ignore-design-docs-test.py | 27 - src/mango/test/12-use-correct-index-test.py | 133 - src/mango/test/13-stable-update-test.py | 51 - src/mango/test/13-users-db-find-test.py | 74 - src/mango/test/14-json-pagination-test.py | 269 - src/mango/test/15-execution-stats-test.py | 79 - src/mango/test/16-index-selectors-test.py | 265 - src/mango/test/17-multi-type-value-test.py | 69 - src/mango/test/18-json-sort.py | 122 - src/mango/test/19-find-conflicts.py | 33 - src/mango/test/20-no-timeout-test.py | 32 - src/mango/test/21-empty-selector-tests.py | 91 - src/mango/test/README.md | 29 - src/mango/test/friend_docs.py | 280 - src/mango/test/limit_docs.py | 105 - src/mango/test/mango.py | 364 -- src/mango/test/user_docs.py | 383 -- src/mango/unittest.cfg | 3 - src/mem3/LICENSE | 202 - src/mem3/README.md | 43 - src/mem3/README_reshard.md | 93 - src/mem3/include/mem3.hrl | 59 - src/mem3/priv/stats_descriptions.cfg | 12 - src/mem3/rebar.config | 14 - src/mem3/rebar.config.script | 22 - src/mem3/src/mem3.app.src | 40 - src/mem3/src/mem3.erl | 508 -- src/mem3/src/mem3_app.erl | 21 - src/mem3/src/mem3_bdu.erl | 111 - src/mem3/src/mem3_cluster.erl | 149 - src/mem3/src/mem3_epi.erl | 49 - src/mem3/src/mem3_hash.erl | 64 - src/mem3/src/mem3_httpd.erl | 118 - src/mem3/src/mem3_httpd_handlers.erl | 25 - src/mem3/src/mem3_nodes.erl | 177 - src/mem3/src/mem3_plugin_couch_db.erl | 20 - src/mem3/src/mem3_rep.erl | 1094 ---- src/mem3/src/mem3_reshard.erl | 851 --- src/mem3/src/mem3_reshard.hrl | 74 - src/mem3/src/mem3_reshard_api.erl | 229 - src/mem3/src/mem3_reshard_dbdoc.erl | 255 - src/mem3/src/mem3_reshard_httpd.erl | 319 - src/mem3/src/mem3_reshard_index.erl | 184 - src/mem3/src/mem3_reshard_job.erl | 669 -- src/mem3/src/mem3_reshard_job_sup.erl | 46 - src/mem3/src/mem3_reshard_store.erl | 269 - src/mem3/src/mem3_reshard_sup.erl | 36 - src/mem3/src/mem3_reshard_validate.erl | 119 - src/mem3/src/mem3_rpc.erl | 797 --- src/mem3/src/mem3_seeds.erl | 176 - src/mem3/src/mem3_shards.erl | 789 --- src/mem3/src/mem3_sup.erl | 41 - src/mem3/src/mem3_sync.erl | 367 -- src/mem3/src/mem3_sync_event.erl | 89 - src/mem3/src/mem3_sync_event_listener.erl | 356 -- src/mem3/src/mem3_sync_nodes.erl | 98 - src/mem3/src/mem3_sync_security.erl | 125 - src/mem3/src/mem3_util.erl | 755 --- src/mem3/test/eunit/mem3_bdu_test.erl | 259 - src/mem3/test/eunit/mem3_cluster_test.erl | 129 - src/mem3/test/eunit/mem3_hash_test.erl | 23 - src/mem3/test/eunit/mem3_rep_test.erl | 318 - src/mem3/test/eunit/mem3_reshard_api_test.erl | 984 --- .../test/eunit/mem3_reshard_changes_feed_test.erl | 398 -- src/mem3/test/eunit/mem3_reshard_test.erl | 990 --- src/mem3/test/eunit/mem3_ring_prop_tests.erl | 160 - src/mem3/test/eunit/mem3_seeds_test.erl | 82 - src/mem3/test/eunit/mem3_shards_test.erl | 130 - src/mem3/test/eunit/mem3_sync_security_test.erl | 57 - src/mem3/test/eunit/mem3_util_test.erl | 152 - src/rexi/README.md | 23 - src/rexi/include/rexi.hrl | 20 - src/rexi/priv/stats_descriptions.cfg | 24 - src/rexi/rebar.config | 2 - src/rexi/src/rexi.app.src | 28 - src/rexi/src/rexi.erl | 330 - src/rexi/src/rexi_app.erl | 21 - src/rexi/src/rexi_buffer.erl | 107 - src/rexi/src/rexi_monitor.erl | 67 - src/rexi/src/rexi_server.erl | 207 - src/rexi/src/rexi_server_mon.erl | 164 - src/rexi/src/rexi_server_sup.erl | 26 - src/rexi/src/rexi_sup.erl | 65 - src/rexi/src/rexi_utils.erl | 105 - src/setup/.gitignore | 4 - src/setup/LICENSE | 203 - src/setup/README.md | 210 - src/setup/src/setup.app.src | 27 - src/setup/src/setup.erl | 395 -- src/setup/src/setup_app.erl | 28 - src/setup/src/setup_epi.erl | 48 - src/setup/src/setup_httpd.erl | 186 - src/setup/src/setup_httpd_handlers.erl | 22 - src/setup/src/setup_sup.erl | 44 - src/setup/test/t-frontend-setup.sh | 71 - src/setup/test/t-single-node-auto-setup.sh | 24 - src/setup/test/t-single-node.sh | 46 - src/setup/test/t.sh | 63 - src/smoosh/README.md | 140 - src/smoosh/operator_guide.md | 398 -- src/smoosh/rebar.config | 2 - src/smoosh/recovery_process_diagram.jpeg | Bin 51388 -> 0 bytes src/smoosh/src/smoosh.app.src | 28 - src/smoosh/src/smoosh.erl | 84 - src/smoosh/src/smoosh_app.erl | 28 - src/smoosh/src/smoosh_channel.erl | 548 -- src/smoosh/src/smoosh_priority_queue.erl | 177 - src/smoosh/src/smoosh_server.erl | 640 -- src/smoosh/src/smoosh_sup.erl | 38 - src/smoosh/src/smoosh_utils.erl | 108 - src/smoosh/test/exunit/scheduling_window_test.exs | 79 - src/smoosh/test/exunit/test_helper.exs | 2 - src/smoosh/test/smoosh_priority_queue_tests.erl | 167 - src/smoosh/test/smoosh_tests.erl | 129 - src/weatherreport/.gitignore | 13 - src/weatherreport/.manifest | 5 - src/weatherreport/LICENSE | 178 - src/weatherreport/README.md | 81 - src/weatherreport/how_to_add_a_check.md | 113 - src/weatherreport/rebar.config | 31 - src/weatherreport/src/weatherreport.app.src | 39 - src/weatherreport/src/weatherreport.erl | 203 - src/weatherreport/src/weatherreport_check.erl | 113 - .../src/weatherreport_check_custodian.erl | 84 - src/weatherreport/src/weatherreport_check_disk.erl | 195 - .../weatherreport_check_internal_replication.erl | 59 - src/weatherreport/src/weatherreport_check_ioq.erl | 101 - .../src/weatherreport_check_mem3_sync.erl | 57 - .../src/weatherreport_check_membership.erl | 68 - .../src/weatherreport_check_memory_use.erl | 69 - .../src/weatherreport_check_message_queues.erl | 60 - .../src/weatherreport_check_node_stats.erl | 68 - .../src/weatherreport_check_nodes_connected.erl | 64 - .../src/weatherreport_check_process_calls.erl | 168 - .../src/weatherreport_check_process_memory.erl | 60 - .../src/weatherreport_check_safe_to_rebuild.erl | 121 - .../src/weatherreport_check_search.erl | 60 - .../src/weatherreport_check_tcp_queues.erl | 92 - src/weatherreport/src/weatherreport_config.erl | 200 - src/weatherreport/src/weatherreport_getopt.erl | 655 -- src/weatherreport/src/weatherreport_log.erl | 78 - src/weatherreport/src/weatherreport_node.erl | 221 - src/weatherreport/src/weatherreport_runner.erl | 96 - src/weatherreport/src/weatherreport_util.erl | 115 - support/build_js.escript | 90 - test/bench/benchbulk.sh | 69 - test/build/test-configure-distclean.sh | 15 - test/build/test-configure.sh | 372 -- test/build/test-make-clean.sh | 20 - test/elixir/.formatter.exs | 6 - test/elixir/.gitignore | 2 - test/elixir/Makefile | 4 - test/elixir/README.md | 256 - test/elixir/config/config.exs | 30 - test/elixir/config/test.exs | 3 - test/elixir/lib/couch.ex | 190 - test/elixir/lib/couch/db_test.ex | 557 -- test/elixir/lib/couch_raw.ex | 105 - test/elixir/lib/ex_unit.ex | 48 - test/elixir/lib/setup.ex | 97 - test/elixir/lib/setup/common.ex | 27 - test/elixir/lib/step.ex | 44 - test/elixir/lib/step/config.ex | 33 - test/elixir/lib/step/create_db.ex | 53 - test/elixir/lib/step/start.ex | 85 - test/elixir/lib/step/user.ex | 103 - test/elixir/lib/suite.ex | 222 - test/elixir/lib/utils.ex | 61 - test/elixir/run.cmd | 7 - test/elixir/test/all_docs_test.exs | 317 - test/elixir/test/attachment_names_test.exs | 112 - test/elixir/test/attachment_paths_test.exs | 177 - test/elixir/test/attachment_ranges_test.exs | 143 - test/elixir/test/attachment_views_test.exs | 142 - test/elixir/test/attachments_multipart_test.exs | 476 -- test/elixir/test/attachments_test.exs | 506 -- test/elixir/test/auth_cache_test.exs | 197 - test/elixir/test/basics_test.exs | 384 -- test/elixir/test/batch_save_test.exs | 42 - test/elixir/test/bulk_docs_test.exs | 154 - test/elixir/test/changes_async_test.exs | 442 -- test/elixir/test/changes_test.exs | 509 -- test/elixir/test/cluster_with_quorum_test.exs | 185 - test/elixir/test/cluster_without_quorum_test.exs | 184 - test/elixir/test/coffee_test.exs | 73 - test/elixir/test/compact_test.exs | 88 - test/elixir/test/config/skip.elixir | 33 - test/elixir/test/config/suite.elixir | 713 --- test/elixir/test/config/test-config.ini | 2 - test/elixir/test/config_test.exs | 184 - test/elixir/test/conflicts_test.exs | 110 - test/elixir/test/cookie_auth_test.exs | 395 -- test/elixir/test/copy_doc_test.exs | 71 - test/elixir/test/data/lorem.txt | 103 - test/elixir/test/data/lorem_b64.txt | 1 - test/elixir/test/design_docs_query_test.exs | 273 - test/elixir/test/design_docs_test.exs | 488 -- test/elixir/test/design_options_test.exs | 74 - test/elixir/test/design_paths_test.exs | 76 - test/elixir/test/erlang_views_test.exs | 117 - test/elixir/test/etags_head_test.exs | 151 - test/elixir/test/form_submit_test.exs | 29 - test/elixir/test/helper_test.exs | 31 - test/elixir/test/http_test.exs | 81 - test/elixir/test/invalid_docids_test.exs | 85 - test/elixir/test/jsonp_test.exs | 116 - test/elixir/test/jwtauth_test.exs | 217 - test/elixir/test/large_docs_text.exs | 40 - test/elixir/test/list_views_test.exs | 581 -- test/elixir/test/local_docs_test.exs | 110 - test/elixir/test/lots_of_docs_test.exs | 116 - test/elixir/test/method_override_test.exs | 55 - test/elixir/test/multiple_rows_test.exs | 136 - test/elixir/test/partition_all_docs_test.exs | 204 - test/elixir/test/partition_crud_test.exs | 369 -- test/elixir/test/partition_ddoc_test.exs | 179 - test/elixir/test/partition_design_docs_test.exs | 16 - test/elixir/test/partition_helpers.exs | 76 - test/elixir/test/partition_mango_test.exs | 736 --- test/elixir/test/partition_size_limit_test.exs | 293 - test/elixir/test/partition_size_test.exs | 361 -- test/elixir/test/partition_view_test.exs | 374 -- test/elixir/test/partition_view_update_test.exs | 160 - test/elixir/test/proxyauth_test.exs | 167 - test/elixir/test/purge_test.exs | 150 - test/elixir/test/reader_acl_test.exs | 254 - test/elixir/test/recreate_doc_test.exs | 165 - test/elixir/test/reduce_builtin_test.exs | 282 - test/elixir/test/reduce_false_test.exs | 50 - test/elixir/test/reduce_test.exs | 632 -- test/elixir/test/replication_test.exs | 1773 ------ test/elixir/test/reshard_all_docs_test.exs | 79 - test/elixir/test/reshard_basic_test.exs | 174 - test/elixir/test/reshard_changes_feed.exs | 81 - test/elixir/test/reshard_helpers.exs | 114 - test/elixir/test/rev_stemming_test.exs | 157 - test/elixir/test/rewrite_js_test.exs | 411 -- test/elixir/test/rewrite_test.exs | 526 -- test/elixir/test/security_validation_test.exs | 324 - test/elixir/test/show_documents_test.exs | 448 -- test/elixir/test/support/couch_test_case.ex | 29 - test/elixir/test/test_helper.exs | 3 - test/elixir/test/update_documents_test.exs | 324 - test/elixir/test/users_db_security_test.exs | 520 -- test/elixir/test/users_db_test.exs | 426 -- test/elixir/test/utf8_test.exs | 65 - test/elixir/test/uuids_test.exs | 96 - test/elixir/test/view_collation_raw_test.exs | 159 - test/elixir/test/view_collation_test.exs | 144 - test/elixir/test/view_compaction_test.exs | 105 - test/elixir/test/view_conflicts_test.exs | 74 - test/elixir/test/view_errors_test.exs | 290 - test/elixir/test/view_include_docs_test.exs | 263 - test/elixir/test/view_multi_key_all_docs_test.exs | 191 - test/elixir/test/view_multi_key_design_test.exs | 346 - test/elixir/test/view_offsets_test.exs | 100 - test/elixir/test/view_pagination_test.exs | 189 - test/elixir/test/view_sandboxing_test.exs | 191 - test/elixir/test/view_test.exs | 155 - test/elixir/test/view_update_seq_test.exs | 142 - test/javascript/tests/list_views.js | 502 -- test/javascript/tests/proxyauth.js | 137 - test/javascript/tests/replicator_db_bad_rep_id.js | 103 - test/javascript/tests/replicator_db_by_doc_id.js | 128 - test/javascript/tests/rewrite.js | 513 -- test/javascript/tests/rewrite_js.js | 366 -- test/javascript/tests/security_validation.js | 330 - test/javascript/tests/show_documents.js | 376 -- test/javascript/tests/users_db_security.js | 418 -- test/random_port.ini | 19 - test/view_server/query_server_spec.rb | 885 --- test/view_server/run_native_process.es | 59 - version.mk | 3 - 1053 files changed, 3 insertions(+), 215792 deletions(-) delete mode 100644 .credo.exs delete mode 100644 .devcontainer/Dockerfile delete mode 100644 .devcontainer/devcontainer.json delete mode 100644 .formatter.exs delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/enhancement.md delete mode 100644 .github/ISSUE_TEMPLATE/rfc.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md delete mode 100644 .gitignore delete mode 100644 .mailmap delete mode 100644 BUGS.md delete mode 100644 COMMITTERS.md delete mode 100644 CONTRIBUTING.md delete mode 100644 CONTRIBUTORS.in delete mode 100644 INSTALL.Unix.md delete mode 100644 INSTALL.Windows.md delete mode 100644 LICENSE delete mode 100644 Makefile delete mode 100644 Makefile.win delete mode 100644 NOTICE delete mode 100644 README-DEV.rst create mode 100644 README.md delete mode 100644 README.rst delete mode 100644 bin/erlang-version.escript delete mode 100644 build-aux/Jenkinsfile.full delete mode 100644 build-aux/Jenkinsfile.pr delete mode 100644 build-aux/README.md delete mode 100755 build-aux/couchdb-build-release.sh delete mode 100755 build-aux/dist-error delete mode 100755 build-aux/introspect delete mode 100755 build-aux/logfile-uploader.py delete mode 100755 build-aux/print-committerlist.sh delete mode 100755 build-aux/show-test-results.py delete mode 100755 build-aux/sphinx-build delete mode 100755 build-aux/sphinx-touch delete mode 100644 config/config.exs delete mode 100644 config/dev.exs delete mode 100644 config/integration.exs delete mode 100644 config/prod.exs delete mode 100644 config/test.exs delete mode 100755 configure delete mode 100644 configure.ps1 delete mode 100644 dev/format_all.py delete mode 100644 dev/format_check.py delete mode 100644 dev/format_lib.py delete mode 100755 dev/make_boot_script delete mode 100644 dev/monitor_parent.erl delete mode 100644 dev/pbkdf2.py delete mode 100755 dev/remsh delete mode 100755 dev/remsh-tls delete mode 100755 dev/run delete mode 100644 dev/run.cmd delete mode 100644 erlang_ls.config delete mode 100644 make.cmd delete mode 100644 mix.exs delete mode 100644 mix.lock delete mode 100644 rebar.config.script delete mode 100644 rel/apps/config.config delete mode 100644 rel/apps/couch_epi.config delete mode 100755 rel/boot_dev_cluster.sh delete mode 100644 rel/files/README delete mode 100644 rel/files/couchdb.cmd.in delete mode 100755 rel/files/couchdb.in delete mode 100644 rel/files/eunit.config delete mode 100644 rel/files/eunit.ini delete mode 100644 rel/files/sys.config delete mode 100644 rel/files/vm.args delete mode 100644 rel/haproxy.cfg delete mode 100755 rel/overlay/bin/remsh delete mode 100644 rel/overlay/etc/default.d/README delete mode 100644 rel/overlay/etc/default.ini delete mode 100644 rel/overlay/etc/local.d/README delete mode 100644 rel/overlay/etc/local.ini delete mode 100644 rel/overlay/etc/vm.args delete mode 100644 rel/plugins/eunit_plugin.erl delete mode 100644 rel/reltool.config delete mode 100644 setup_eunit.template delete mode 100644 share/server/60/escodegen.js delete mode 100644 share/server/60/esprima.js delete mode 100644 share/server/60/rewrite_fun.js delete mode 100644 share/server/coffee-script.js delete mode 100644 share/server/dreyfus.js delete mode 100644 share/server/filter.js delete mode 100644 share/server/json2.js delete mode 100644 share/server/loop.js delete mode 100644 share/server/mimeparse.js delete mode 100644 share/server/render.js delete mode 100644 share/server/rewrite_fun.js delete mode 100644 share/server/state.js delete mode 100644 share/server/util.js delete mode 100644 share/server/validate.js delete mode 100644 share/server/views.js delete mode 100644 src/chttpd/LICENSE delete mode 100644 src/chttpd/include/chttpd.hrl delete mode 100644 src/chttpd/include/chttpd_cors.hrl delete mode 100644 src/chttpd/priv/stats_descriptions.cfg delete mode 100644 src/chttpd/rebar.config delete mode 100644 src/chttpd/src/chttpd.app.src delete mode 100644 src/chttpd/src/chttpd.erl delete mode 100644 src/chttpd/src/chttpd_app.erl delete mode 100644 src/chttpd/src/chttpd_auth.erl delete mode 100644 src/chttpd/src/chttpd_auth_cache.erl delete mode 100644 src/chttpd/src/chttpd_auth_request.erl delete mode 100644 src/chttpd/src/chttpd_cors.erl delete mode 100644 src/chttpd/src/chttpd_db.erl delete mode 100644 src/chttpd/src/chttpd_epi.erl delete mode 100644 src/chttpd/src/chttpd_external.erl delete mode 100644 src/chttpd/src/chttpd_handlers.erl delete mode 100644 src/chttpd/src/chttpd_httpd_handlers.erl delete mode 100644 src/chttpd/src/chttpd_misc.erl delete mode 100644 src/chttpd/src/chttpd_node.erl delete mode 100644 src/chttpd/src/chttpd_plugin.erl delete mode 100644 src/chttpd/src/chttpd_prefer_header.erl delete mode 100644 src/chttpd/src/chttpd_rewrite.erl delete mode 100644 src/chttpd/src/chttpd_show.erl delete mode 100644 src/chttpd/src/chttpd_stats.erl delete mode 100644 src/chttpd/src/chttpd_sup.erl delete mode 100644 src/chttpd/src/chttpd_test_util.erl delete mode 100644 src/chttpd/src/chttpd_util.erl delete mode 100644 src/chttpd/src/chttpd_view.erl delete mode 100644 src/chttpd/src/chttpd_xframe_options.erl delete mode 100644 src/chttpd/test/eunit/chttpd_auth_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_cors_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_csp_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_db_bulk_get_multipart_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_db_bulk_get_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_db_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_dbs_info_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_delayed_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_error_info_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_external_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_handlers_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_open_revs_error_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_plugin_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_prefer_header_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_purge_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_revs_diff_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_security_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_session_tests.erl delete mode 100644 src/chttpd/test/eunit/chttpd_socket_buffer_size_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_test.hrl delete mode 100644 src/chttpd/test/eunit/chttpd_util_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_view_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_welcome_test.erl delete mode 100644 src/chttpd/test/eunit/chttpd_xframe_test.erl delete mode 100644 src/couch/.gitignore delete mode 100644 src/couch/LICENSE delete mode 100644 src/couch/include/couch_db.hrl delete mode 100644 src/couch/include/couch_eunit.hrl delete mode 100644 src/couch/include/couch_eunit_proper.hrl delete mode 100644 src/couch/include/couch_js_functions.hrl delete mode 100644 src/couch/priv/couch_ejson_compare/couch_ejson_compare.c delete mode 100644 src/couch/priv/couch_js/1.8.5/help.h delete mode 100644 src/couch/priv/couch_js/1.8.5/main.c delete mode 100644 src/couch/priv/couch_js/1.8.5/utf8.c delete mode 100644 src/couch/priv/couch_js/1.8.5/utf8.h delete mode 100644 src/couch/priv/couch_js/1.8.5/util.c delete mode 100644 src/couch/priv/couch_js/1.8.5/util.h delete mode 100644 src/couch/priv/couch_js/60/help.h delete mode 100644 src/couch/priv/couch_js/60/main.cpp delete mode 100644 src/couch/priv/couch_js/60/util.cpp delete mode 100644 src/couch/priv/couch_js/60/util.h delete mode 100644 src/couch/priv/couch_js/68/help.h delete mode 100644 src/couch/priv/couch_js/68/main.cpp delete mode 100644 src/couch/priv/couch_js/68/util.cpp delete mode 100644 src/couch/priv/couch_js/68/util.h delete mode 100644 src/couch/priv/couch_js/86/help.h delete mode 100644 src/couch/priv/couch_js/86/main.cpp delete mode 100644 src/couch/priv/couch_js/86/util.cpp delete mode 100644 src/couch/priv/couch_js/86/util.h delete mode 100755 src/couch/priv/spawnkillable/couchspawnkillable.sh delete mode 100644 src/couch/priv/spawnkillable/couchspawnkillable_win.c delete mode 100644 src/couch/priv/stats_descriptions.cfg delete mode 100644 src/couch/rebar.config.script delete mode 100644 src/couch/src/couch.app.src delete mode 100644 src/couch/src/couch.erl delete mode 100644 src/couch/src/couch_app.erl delete mode 100644 src/couch/src/couch_att.erl delete mode 100644 src/couch/src/couch_auth_cache.erl delete mode 100644 src/couch/src/couch_base32.erl delete mode 100644 src/couch/src/couch_bt_engine.erl delete mode 100644 src/couch/src/couch_bt_engine.hrl delete mode 100644 src/couch/src/couch_bt_engine_compactor.erl delete mode 100644 src/couch/src/couch_bt_engine_header.erl delete mode 100644 src/couch/src/couch_bt_engine_stream.erl delete mode 100644 src/couch/src/couch_btree.erl delete mode 100644 src/couch/src/couch_changes.erl delete mode 100644 src/couch/src/couch_compress.erl delete mode 100644 src/couch/src/couch_db.erl delete mode 100644 src/couch/src/couch_db_engine.erl delete mode 100644 src/couch/src/couch_db_epi.erl delete mode 100644 src/couch/src/couch_db_header.erl delete mode 100644 src/couch/src/couch_db_int.hrl delete mode 100644 src/couch/src/couch_db_plugin.erl delete mode 100644 src/couch/src/couch_db_split.erl delete mode 100644 src/couch/src/couch_db_updater.erl delete mode 100644 src/couch/src/couch_debug.erl delete mode 100644 src/couch/src/couch_doc.erl delete mode 100644 src/couch/src/couch_ejson_compare.erl delete mode 100644 src/couch/src/couch_ejson_size.erl delete mode 100644 src/couch/src/couch_emsort.erl delete mode 100644 src/couch/src/couch_event_sup.erl delete mode 100644 src/couch/src/couch_file.erl delete mode 100644 src/couch/src/couch_flags.erl delete mode 100644 src/couch/src/couch_flags_config.erl delete mode 100644 src/couch/src/couch_hash.erl delete mode 100644 src/couch/src/couch_hotp.erl delete mode 100644 src/couch/src/couch_httpd.erl delete mode 100644 src/couch/src/couch_httpd_auth.erl delete mode 100644 src/couch/src/couch_httpd_db.erl delete mode 100644 src/couch/src/couch_httpd_handlers.erl delete mode 100644 src/couch/src/couch_httpd_misc_handlers.erl delete mode 100644 src/couch/src/couch_httpd_multipart.erl delete mode 100644 src/couch/src/couch_httpd_rewrite.erl delete mode 100644 src/couch/src/couch_httpd_vhost.erl delete mode 100644 src/couch/src/couch_io_logger.erl delete mode 100644 src/couch/src/couch_key_tree.erl delete mode 100644 src/couch/src/couch_lru.erl delete mode 100644 src/couch/src/couch_multidb_changes.erl delete mode 100644 src/couch/src/couch_native_process.erl delete mode 100644 src/couch/src/couch_os_process.erl delete mode 100644 src/couch/src/couch_partition.erl delete mode 100644 src/couch/src/couch_passwords.erl delete mode 100644 src/couch/src/couch_primary_sup.erl delete mode 100644 src/couch/src/couch_proc_manager.erl delete mode 100644 src/couch/src/couch_query_servers.erl delete mode 100644 src/couch/src/couch_rand.erl delete mode 100644 src/couch/src/couch_secondary_sup.erl delete mode 100644 src/couch/src/couch_server.erl delete mode 100644 src/couch/src/couch_server_int.hrl delete mode 100644 src/couch/src/couch_stream.erl delete mode 100644 src/couch/src/couch_sup.erl delete mode 100644 src/couch/src/couch_task_status.erl delete mode 100644 src/couch/src/couch_totp.erl delete mode 100644 src/couch/src/couch_users_db.erl delete mode 100644 src/couch/src/couch_util.erl delete mode 100644 src/couch/src/couch_uuids.erl delete mode 100644 src/couch/src/couch_work_queue.erl delete mode 100644 src/couch/src/test_request.erl delete mode 100644 src/couch/src/test_util.erl delete mode 100644 src/couch/test/eunit/chttpd_endpoints_tests.erl delete mode 100644 src/couch/test/eunit/couch_auth_cache_tests.erl delete mode 100644 src/couch/test/eunit/couch_base32_tests.erl delete mode 100644 src/couch/test/eunit/couch_bt_engine_compactor_ev.erl delete mode 100644 src/couch/test/eunit/couch_bt_engine_compactor_ev_tests.erl delete mode 100644 src/couch/test/eunit/couch_bt_engine_compactor_tests.erl delete mode 100644 src/couch/test/eunit/couch_bt_engine_tests.erl delete mode 100644 src/couch/test/eunit/couch_bt_engine_upgrade_tests.erl delete mode 100644 src/couch/test/eunit/couch_btree_tests.erl delete mode 100644 src/couch/test/eunit/couch_changes_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_doc_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_mpr_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_plugin_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_props_upgrade_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_split_tests.erl delete mode 100644 src/couch/test/eunit/couch_db_tests.erl delete mode 100644 src/couch/test/eunit/couch_doc_json_tests.erl delete mode 100644 src/couch/test/eunit/couch_doc_tests.erl delete mode 100644 src/couch/test/eunit/couch_ejson_compare_tests.erl delete mode 100644 src/couch/test/eunit/couch_ejson_size_tests.erl delete mode 100644 src/couch/test/eunit/couch_etag_tests.erl delete mode 100644 src/couch/test/eunit/couch_file_tests.erl delete mode 100644 src/couch/test/eunit/couch_flags_config_tests.erl delete mode 100644 src/couch/test/eunit/couch_flags_tests.erl delete mode 100644 src/couch/test/eunit/couch_hotp_tests.erl delete mode 100644 src/couch/test/eunit/couch_index_tests.erl delete mode 100644 src/couch/test/eunit/couch_js_tests.erl delete mode 100644 src/couch/test/eunit/couch_key_tree_prop_tests.erl delete mode 100644 src/couch/test/eunit/couch_key_tree_tests.erl delete mode 100644 src/couch/test/eunit/couch_passwords_tests.erl delete mode 100644 src/couch/test/eunit/couch_query_servers_tests.erl delete mode 100644 src/couch/test/eunit/couch_server_tests.erl delete mode 100644 src/couch/test/eunit/couch_stream_tests.erl delete mode 100644 src/couch/test/eunit/couch_task_status_tests.erl delete mode 100644 src/couch/test/eunit/couch_totp_tests.erl delete mode 100644 src/couch/test/eunit/couch_util_tests.erl delete mode 100644 src/couch/test/eunit/couch_uuids_tests.erl delete mode 100644 src/couch/test/eunit/couch_work_queue_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_attachments_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_auth_tests.erl delete mode 100755 src/couch/test/eunit/couchdb_cookie_domain_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_cors_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_db_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_design_doc_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_file_compression_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_location_header_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_mrview_cors_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_mrview_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_os_proc_pool.erl delete mode 100644 src/couch/test/eunit/couchdb_update_conflicts_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_vhosts_tests.erl delete mode 100644 src/couch/test/eunit/couchdb_views_tests.erl delete mode 100644 src/couch/test/eunit/fixtures/15a5cb17365a99cd9ddc7327c82bbd0d.view delete mode 100644 src/couch/test/eunit/fixtures/1f2c24bc334d701c2048f85e7438eef1.view delete mode 100644 src/couch/test/eunit/fixtures/6cf2c2f766f87b618edf6630b00f8736.view delete mode 100644 src/couch/test/eunit/fixtures/colltest1.couch delete mode 100644 src/couch/test/eunit/fixtures/couch_stats_aggregates.cfg delete mode 100644 src/couch/test/eunit/fixtures/couch_stats_aggregates.ini delete mode 100644 src/couch/test/eunit/fixtures/db321.couch delete mode 100644 src/couch/test/eunit/fixtures/db_non_partitioned.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v6_with_1_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v6_with_1_purge_req_for_2_docs.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v6_with_2_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v6_without_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v7_with_1_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v7_with_1_purge_req_for_2_docs.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v7_with_2_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/db_v7_without_purge_req.couch delete mode 100644 src/couch/test/eunit/fixtures/logo.png delete mode 100644 src/couch/test/eunit/fixtures/multipart.http delete mode 100644 src/couch/test/eunit/fixtures/os_daemon_bad_perm.sh delete mode 100755 src/couch/test/eunit/fixtures/os_daemon_can_reboot.sh delete mode 100755 src/couch/test/eunit/fixtures/os_daemon_configer.escript delete mode 100755 src/couch/test/eunit/fixtures/os_daemon_die_on_boot.sh delete mode 100755 src/couch/test/eunit/fixtures/os_daemon_die_quickly.sh delete mode 100755 src/couch/test/eunit/fixtures/os_daemon_looper.escript delete mode 100644 src/couch/test/eunit/fixtures/test.couch delete mode 100644 src/couch/test/eunit/global_changes_tests.erl delete mode 100644 src/couch/test/eunit/json_stream_parse_tests.erl delete mode 100644 src/couch/test/eunit/test_web.erl delete mode 100644 src/couch/test/exunit/couch_compress_tests.exs delete mode 100644 src/couch/test/exunit/fabric_test.exs delete mode 100644 src/couch/test/exunit/same_site_cookie_tests.exs delete mode 100644 src/couch/test/exunit/test_helper.exs delete mode 100644 src/couch_dist/LICENSE delete mode 100644 src/couch_dist/rebar.config delete mode 100644 src/couch_dist/src/couch_dist.app.src delete mode 100644 src/couch_dist/src/couch_dist.erl delete mode 100644 src/couch_dist/test/eunit/couch_dist_tests.erl delete mode 100644 src/couch_epi/.gitignore delete mode 100644 src/couch_epi/LICENSE delete mode 100644 src/couch_epi/README.md delete mode 100644 src/couch_epi/rebar.config delete mode 100644 src/couch_epi/src/couch_epi.app.src.script delete mode 100644 src/couch_epi/src/couch_epi.erl delete mode 100644 src/couch_epi/src/couch_epi.hrl delete mode 100644 src/couch_epi/src/couch_epi_app.erl delete mode 100644 src/couch_epi/src/couch_epi_codechange_monitor.erl delete mode 100644 src/couch_epi/src/couch_epi_codegen.erl delete mode 100644 src/couch_epi/src/couch_epi_data.erl delete mode 100644 src/couch_epi/src/couch_epi_data_gen.erl delete mode 100644 src/couch_epi/src/couch_epi_functions.erl delete mode 100644 src/couch_epi/src/couch_epi_functions_gen.erl delete mode 100644 src/couch_epi/src/couch_epi_module_keeper.erl delete mode 100644 src/couch_epi/src/couch_epi_plugin.erl delete mode 100644 src/couch_epi/src/couch_epi_sup.erl delete mode 100644 src/couch_epi/src/couch_epi_util.erl delete mode 100644 src/couch_epi/test/eunit/couch_epi_basic_test.erl delete mode 100644 src/couch_epi/test/eunit/couch_epi_tests.erl delete mode 100644 src/couch_epi/test/eunit/fixtures/app_data1.cfg delete mode 100644 src/couch_epi/test/eunit/fixtures/app_data2.cfg delete mode 100644 src/couch_event/.gitignore delete mode 100644 src/couch_event/LICENSE delete mode 100644 src/couch_event/README.md delete mode 100644 src/couch_event/rebar.config delete mode 100644 src/couch_event/src/couch_event.app.src delete mode 100644 src/couch_event/src/couch_event.erl delete mode 100644 src/couch_event/src/couch_event_app.erl delete mode 100644 src/couch_event/src/couch_event_int.hrl delete mode 100644 src/couch_event/src/couch_event_listener.erl delete mode 100644 src/couch_event/src/couch_event_listener_mfa.erl delete mode 100644 src/couch_event/src/couch_event_os_listener.erl delete mode 100644 src/couch_event/src/couch_event_server.erl delete mode 100644 src/couch_event/src/couch_event_sup2.erl delete mode 100644 src/couch_index/.gitignore delete mode 100644 src/couch_index/LICENSE delete mode 100644 src/couch_index/rebar.config delete mode 100644 src/couch_index/src/couch_index.app.src delete mode 100644 src/couch_index/src/couch_index.erl delete mode 100644 src/couch_index/src/couch_index_app.erl delete mode 100644 src/couch_index/src/couch_index_compactor.erl delete mode 100644 src/couch_index/src/couch_index_debug.erl delete mode 100644 src/couch_index/src/couch_index_epi.erl delete mode 100644 src/couch_index/src/couch_index_plugin.erl delete mode 100644 src/couch_index/src/couch_index_plugin_couch_db.erl delete mode 100644 src/couch_index/src/couch_index_server.erl delete mode 100644 src/couch_index/src/couch_index_sup.erl delete mode 100644 src/couch_index/src/couch_index_updater.erl delete mode 100644 src/couch_index/src/couch_index_util.erl delete mode 100644 src/couch_index/test/eunit/couch_index_compaction_tests.erl delete mode 100644 src/couch_index/test/eunit/couch_index_ddoc_updated_tests.erl delete mode 100644 src/couch_log/.gitignore delete mode 100644 src/couch_log/LICENSE delete mode 100644 src/couch_log/include/couch_log.hrl delete mode 100644 src/couch_log/priv/stats_descriptions.cfg delete mode 100644 src/couch_log/rebar.config delete mode 100644 src/couch_log/src/couch_log.app.src delete mode 100644 src/couch_log/src/couch_log.erl delete mode 100644 src/couch_log/src/couch_log_app.erl delete mode 100644 src/couch_log/src/couch_log_config.erl delete mode 100644 src/couch_log/src/couch_log_config_dyn.erl delete mode 100644 src/couch_log/src/couch_log_error_logger_h.erl delete mode 100644 src/couch_log/src/couch_log_formatter.erl delete mode 100644 src/couch_log/src/couch_log_monitor.erl delete mode 100644 src/couch_log/src/couch_log_server.erl delete mode 100644 src/couch_log/src/couch_log_sup.erl delete mode 100644 src/couch_log/src/couch_log_trunc_io.erl delete mode 100644 src/couch_log/src/couch_log_trunc_io_fmt.erl delete mode 100644 src/couch_log/src/couch_log_util.erl delete mode 100644 src/couch_log/src/couch_log_writer.erl delete mode 100644 src/couch_log/src/couch_log_writer_file.erl delete mode 100644 src/couch_log/src/couch_log_writer_journald.erl delete mode 100644 src/couch_log/src/couch_log_writer_stderr.erl delete mode 100644 src/couch_log/src/couch_log_writer_syslog.erl delete mode 100644 src/couch_log/test/eunit/couch_log_config_listener_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_config_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_error_logger_h_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_formatter_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_monitor_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_server_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_test_util.erl delete mode 100644 src/couch_log/test/eunit/couch_log_trunc_io_fmt_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_util_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_writer_ets.erl delete mode 100644 src/couch_log/test/eunit/couch_log_writer_file_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_writer_stderr_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_writer_syslog_test.erl delete mode 100644 src/couch_log/test/eunit/couch_log_writer_test.erl delete mode 100644 src/couch_mrview/LICENSE delete mode 100644 src/couch_mrview/include/couch_mrview.hrl delete mode 100644 src/couch_mrview/priv/stats_descriptions.cfg delete mode 100644 src/couch_mrview/rebar.config delete mode 100644 src/couch_mrview/src/couch_mrview.app.src delete mode 100644 src/couch_mrview/src/couch_mrview.erl delete mode 100644 src/couch_mrview/src/couch_mrview_cleanup.erl delete mode 100644 src/couch_mrview/src/couch_mrview_compactor.erl delete mode 100644 src/couch_mrview/src/couch_mrview_debug.erl delete mode 100644 src/couch_mrview/src/couch_mrview_http.erl delete mode 100644 src/couch_mrview/src/couch_mrview_index.erl delete mode 100644 src/couch_mrview/src/couch_mrview_show.erl delete mode 100644 src/couch_mrview/src/couch_mrview_test_util.erl delete mode 100644 src/couch_mrview/src/couch_mrview_update_notifier.erl delete mode 100644 src/couch_mrview/src/couch_mrview_updater.erl delete mode 100644 src/couch_mrview/src/couch_mrview_util.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_all_docs_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_collation_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_compact_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_ddoc_updated_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_ddoc_validation_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_design_docs_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_http_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_index_info_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_local_docs_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_map_views_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_purge_docs_fabric_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_purge_docs_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_red_views_tests.erl delete mode 100644 src/couch_mrview/test/eunit/couch_mrview_util_tests.erl delete mode 100644 src/couch_peruser/.gitignore delete mode 100644 src/couch_peruser/LICENSE delete mode 100644 src/couch_peruser/README.md delete mode 100644 src/couch_peruser/src/couch_peruser.app.src delete mode 100644 src/couch_peruser/src/couch_peruser.erl delete mode 100644 src/couch_peruser/src/couch_peruser_app.erl delete mode 100644 src/couch_peruser/src/couch_peruser_sup.erl delete mode 100644 src/couch_peruser/test/eunit/couch_peruser_test.erl delete mode 100644 src/couch_plugins/LICENSE delete mode 100644 src/couch_plugins/Makefile.am delete mode 100644 src/couch_plugins/README.md delete mode 100644 src/couch_plugins/src/couch_plugins.app.src delete mode 100644 src/couch_plugins/src/couch_plugins.erl delete mode 100644 src/couch_plugins/src/couch_plugins_httpd.erl delete mode 100644 src/couch_prometheus/src/couch_prometheus.app.src delete mode 100644 src/couch_prometheus/src/couch_prometheus.hrl delete mode 100644 src/couch_prometheus/src/couch_prometheus_app.erl delete mode 100644 src/couch_prometheus/src/couch_prometheus_http.erl delete mode 100644 src/couch_prometheus/src/couch_prometheus_server.erl delete mode 100644 src/couch_prometheus/src/couch_prometheus_sup.erl delete mode 100644 src/couch_prometheus/src/couch_prometheus_util.erl delete mode 100644 src/couch_prometheus/test/eunit/couch_prometheus_e2e_tests.erl delete mode 100644 src/couch_prometheus/test/eunit/couch_prometheus_util_tests.erl delete mode 100644 src/couch_pse_tests/src/couch_pse_tests.app.src delete mode 100644 src/couch_pse_tests/src/cpse_gather.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_attachments.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_compaction.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_copy_purge_infos.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_fold_changes.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_fold_docs.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_fold_purge_infos.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_get_set_props.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_open_close_delete.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_purge_bad_checkpoints.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_purge_docs.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_purge_replication.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_purge_seqs.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_read_write_docs.erl delete mode 100644 src/couch_pse_tests/src/cpse_test_ref_counting.erl delete mode 100644 src/couch_pse_tests/src/cpse_util.erl delete mode 100644 src/couch_replicator/.gitignore delete mode 100644 src/couch_replicator/LICENSE delete mode 100644 src/couch_replicator/README.md delete mode 100644 src/couch_replicator/include/couch_replicator_api_wrap.hrl delete mode 100644 src/couch_replicator/priv/stats_descriptions.cfg delete mode 100644 src/couch_replicator/src/couch_replicator.app.src delete mode 100644 src/couch_replicator/src/couch_replicator.erl delete mode 100644 src/couch_replicator/src/couch_replicator.hrl delete mode 100644 src/couch_replicator/src/couch_replicator_api_wrap.erl delete mode 100644 src/couch_replicator/src/couch_replicator_app.erl delete mode 100644 src/couch_replicator/src/couch_replicator_auth.erl delete mode 100644 src/couch_replicator/src/couch_replicator_auth_noop.erl delete mode 100644 src/couch_replicator/src/couch_replicator_auth_session.erl delete mode 100644 src/couch_replicator/src/couch_replicator_changes_reader.erl delete mode 100644 src/couch_replicator/src/couch_replicator_clustering.erl delete mode 100644 src/couch_replicator/src/couch_replicator_connection.erl delete mode 100644 src/couch_replicator/src/couch_replicator_db_changes.erl delete mode 100644 src/couch_replicator/src/couch_replicator_doc_processor.erl delete mode 100644 src/couch_replicator/src/couch_replicator_doc_processor_worker.erl delete mode 100644 src/couch_replicator/src/couch_replicator_docs.erl delete mode 100644 src/couch_replicator/src/couch_replicator_fabric.erl delete mode 100644 src/couch_replicator/src/couch_replicator_fabric_rpc.erl delete mode 100644 src/couch_replicator/src/couch_replicator_filters.erl delete mode 100644 src/couch_replicator/src/couch_replicator_httpc.erl delete mode 100644 src/couch_replicator/src/couch_replicator_httpc_pool.erl delete mode 100644 src/couch_replicator/src/couch_replicator_httpd.erl delete mode 100644 src/couch_replicator/src/couch_replicator_httpd_util.erl delete mode 100644 src/couch_replicator/src/couch_replicator_ids.erl delete mode 100644 src/couch_replicator/src/couch_replicator_job_sup.erl delete mode 100644 src/couch_replicator/src/couch_replicator_js_functions.hrl delete mode 100644 src/couch_replicator/src/couch_replicator_notifier.erl delete mode 100644 src/couch_replicator/src/couch_replicator_rate_limiter.erl delete mode 100644 src/couch_replicator/src/couch_replicator_rate_limiter_tables.erl delete mode 100644 src/couch_replicator/src/couch_replicator_scheduler.erl delete mode 100644 src/couch_replicator/src/couch_replicator_scheduler_job.erl delete mode 100644 src/couch_replicator/src/couch_replicator_scheduler_sup.erl delete mode 100644 src/couch_replicator/src/couch_replicator_share.erl delete mode 100644 src/couch_replicator/src/couch_replicator_stats.erl delete mode 100644 src/couch_replicator/src/couch_replicator_sup.erl delete mode 100644 src/couch_replicator/src/couch_replicator_utils.erl delete mode 100644 src/couch_replicator/src/couch_replicator_worker.erl delete mode 100644 src/couch_replicator/src/json_stream_parse.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_attachments_too_large.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_compact_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_connection_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_create_target_with_options_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_error_reporting_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_httpc_pool_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_large_atts_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_many_leaves_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_missing_stubs_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_rate_limiter_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_retain_stats_between_job_runs.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_test.hrl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_test_helper.erl delete mode 100644 src/couch_replicator/test/eunit/couch_replicator_use_checkpoints_tests.erl delete mode 100644 src/couch_stats/.gitignore delete mode 100644 src/couch_stats/LICENSE delete mode 100644 src/couch_stats/README.md delete mode 100644 src/couch_stats/priv/sample_descriptions.cfg delete mode 100644 src/couch_stats/src/couch_stats.app.src delete mode 100644 src/couch_stats/src/couch_stats.erl delete mode 100644 src/couch_stats/src/couch_stats.hrl delete mode 100644 src/couch_stats/src/couch_stats_aggregator.erl delete mode 100644 src/couch_stats/src/couch_stats_app.erl delete mode 100644 src/couch_stats/src/couch_stats_httpd.erl delete mode 100644 src/couch_stats/src/couch_stats_process_tracker.erl delete mode 100644 src/couch_stats/src/couch_stats_sup.erl delete mode 100644 src/couch_tests/.gitignore delete mode 100644 src/couch_tests/include/couch_tests.hrl delete mode 100644 src/couch_tests/rebar.config delete mode 100644 src/couch_tests/setups/couch_epi_dispatch.erl delete mode 100644 src/couch_tests/src/couch_tests.app.src delete mode 100644 src/couch_tests/src/couch_tests.erl delete mode 100644 src/couch_tests/src/couch_tests_combinatorics.erl delete mode 100644 src/couch_tests/test/couch_tests_app_tests.erl delete mode 100644 src/custodian/README delete mode 100644 src/custodian/rebar.config.script delete mode 100644 src/custodian/src/custodian.app.src.script delete mode 100644 src/custodian/src/custodian.erl delete mode 100644 src/custodian/src/custodian_app.erl delete mode 100644 src/custodian/src/custodian_db_checker.erl delete mode 100644 src/custodian/src/custodian_monitor.erl delete mode 100644 src/custodian/src/custodian_noop_monitor.erl delete mode 100644 src/custodian/src/custodian_server.erl delete mode 100644 src/custodian/src/custodian_sup.erl delete mode 100644 src/custodian/src/custodian_util.erl delete mode 100644 src/ddoc_cache/LICENSE delete mode 100644 src/ddoc_cache/README.md delete mode 100644 src/ddoc_cache/priv/stats_descriptions.cfg delete mode 100644 src/ddoc_cache/src/ddoc_cache.app.src delete mode 100644 src/ddoc_cache/src/ddoc_cache.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache.hrl delete mode 100644 src/ddoc_cache/src/ddoc_cache_app.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_entry.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_entry_custom.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_entry_ddocid.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_entry_ddocid_rev.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_entry_validation_funs.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_lru.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_sup.erl delete mode 100644 src/ddoc_cache/src/ddoc_cache_value.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_basic_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_coverage_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_disabled_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_entry_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_ev.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_eviction_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_lru_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_no_cache_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_open_error_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_open_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_refresh_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_remove_test.erl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_test.hrl delete mode 100644 src/ddoc_cache/test/eunit/ddoc_cache_tutil.erl delete mode 100644 src/dreyfus/.gitignore delete mode 100644 src/dreyfus/LICENSE.txt delete mode 100644 src/dreyfus/README.md delete mode 100644 src/dreyfus/include/dreyfus.hrl delete mode 100644 src/dreyfus/priv/stats_descriptions.cfg delete mode 100644 src/dreyfus/src/clouseau_rpc.erl delete mode 100644 src/dreyfus/src/dreyfus.app.src delete mode 100644 src/dreyfus/src/dreyfus.erl delete mode 100644 src/dreyfus/src/dreyfus_app.erl delete mode 100644 src/dreyfus/src/dreyfus_bookmark.erl delete mode 100644 src/dreyfus/src/dreyfus_config.erl delete mode 100644 src/dreyfus/src/dreyfus_epi.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric_cleanup.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric_group1.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric_group2.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric_info.erl delete mode 100644 src/dreyfus/src/dreyfus_fabric_search.erl delete mode 100644 src/dreyfus/src/dreyfus_httpd.erl delete mode 100644 src/dreyfus/src/dreyfus_httpd_handlers.erl delete mode 100644 src/dreyfus/src/dreyfus_index.erl delete mode 100644 src/dreyfus/src/dreyfus_index_manager.erl delete mode 100644 src/dreyfus/src/dreyfus_index_updater.erl delete mode 100644 src/dreyfus/src/dreyfus_plugin_couch_db.erl delete mode 100644 src/dreyfus/src/dreyfus_rpc.erl delete mode 100644 src/dreyfus/src/dreyfus_sup.erl delete mode 100644 src/dreyfus/src/dreyfus_util.erl delete mode 100644 src/dreyfus/test/dreyfus_blacklist_await_test.erl delete mode 100644 src/dreyfus/test/dreyfus_blacklist_request_test.erl delete mode 100644 src/dreyfus/test/dreyfus_config_test.erl delete mode 100644 src/dreyfus/test/dreyfus_purge_test.erl delete mode 100644 src/dreyfus/test/dreyfus_test_util.erl delete mode 100644 src/dreyfus/test/elixir/mix.exs delete mode 100644 src/dreyfus/test/elixir/mix.lock delete mode 100755 src/dreyfus/test/elixir/run delete mode 100644 src/dreyfus/test/elixir/test/partition_search_test.exs delete mode 100644 src/dreyfus/test/elixir/test/search_test.exs delete mode 100644 src/dreyfus/test/elixir/test/test_helper.exs delete mode 100644 src/fabric/LICENSE delete mode 100644 src/fabric/README.md delete mode 100644 src/fabric/include/fabric.hrl delete mode 100644 src/fabric/priv/stats_descriptions.cfg delete mode 100644 src/fabric/rebar.config delete mode 100644 src/fabric/src/fabric.app.src delete mode 100644 src/fabric/src/fabric.erl delete mode 100644 src/fabric/src/fabric_db_create.erl delete mode 100644 src/fabric/src/fabric_db_delete.erl delete mode 100644 src/fabric/src/fabric_db_doc_count.erl delete mode 100644 src/fabric/src/fabric_db_info.erl delete mode 100644 src/fabric/src/fabric_db_meta.erl delete mode 100644 src/fabric/src/fabric_db_partition_info.erl delete mode 100644 src/fabric/src/fabric_db_update_listener.erl delete mode 100644 src/fabric/src/fabric_db_uuids.erl delete mode 100644 src/fabric/src/fabric_design_doc_count.erl delete mode 100644 src/fabric/src/fabric_dict.erl delete mode 100644 src/fabric/src/fabric_doc_atts.erl delete mode 100644 src/fabric/src/fabric_doc_missing_revs.erl delete mode 100644 src/fabric/src/fabric_doc_open.erl delete mode 100644 src/fabric/src/fabric_doc_open_revs.erl delete mode 100644 src/fabric/src/fabric_doc_purge.erl delete mode 100644 src/fabric/src/fabric_doc_update.erl delete mode 100644 src/fabric/src/fabric_group_info.erl delete mode 100644 src/fabric/src/fabric_ring.erl delete mode 100644 src/fabric/src/fabric_rpc.erl delete mode 100644 src/fabric/src/fabric_streams.erl delete mode 100644 src/fabric/src/fabric_util.erl delete mode 100644 src/fabric/src/fabric_view.erl delete mode 100644 src/fabric/src/fabric_view_all_docs.erl delete mode 100644 src/fabric/src/fabric_view_changes.erl delete mode 100644 src/fabric/src/fabric_view_map.erl delete mode 100644 src/fabric/src/fabric_view_reduce.erl delete mode 100644 src/fabric/test/eunit/fabric_db_create_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_db_info_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_db_uuids_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_moved_shards_seq_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_rpc_purge_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_rpc_tests.erl delete mode 100644 src/fabric/test/eunit/fabric_tests.erl delete mode 100644 src/global_changes/.gitignore delete mode 100644 src/global_changes/LICENSE delete mode 100644 src/global_changes/README.md delete mode 100644 src/global_changes/priv/stats_descriptions.cfg delete mode 100644 src/global_changes/src/global_changes.app.src delete mode 100644 src/global_changes/src/global_changes_app.erl delete mode 100644 src/global_changes/src/global_changes_epi.erl delete mode 100644 src/global_changes/src/global_changes_httpd.erl delete mode 100644 src/global_changes/src/global_changes_httpd_handlers.erl delete mode 100644 src/global_changes/src/global_changes_listener.erl delete mode 100644 src/global_changes/src/global_changes_plugin.erl delete mode 100644 src/global_changes/src/global_changes_server.erl delete mode 100644 src/global_changes/src/global_changes_sup.erl delete mode 100644 src/global_changes/src/global_changes_util.erl delete mode 100644 src/global_changes/test/eunit/global_changes_hooks_tests.erl delete mode 100644 src/ioq/.gitignore delete mode 100644 src/ioq/src/ioq.app.src delete mode 100644 src/ioq/src/ioq.erl delete mode 100644 src/ioq/src/ioq_app.erl delete mode 100644 src/ioq/src/ioq_sup.erl delete mode 100644 src/jwtf/.gitignore delete mode 100644 src/jwtf/LICENSE delete mode 100644 src/jwtf/README.md delete mode 100644 src/jwtf/rebar.config delete mode 100644 src/jwtf/src/jwtf.app.src delete mode 100644 src/jwtf/src/jwtf.erl delete mode 100644 src/jwtf/src/jwtf_app.erl delete mode 100644 src/jwtf/src/jwtf_keystore.erl delete mode 100644 src/jwtf/src/jwtf_sup.erl delete mode 100644 src/jwtf/test/jwtf_keystore_tests.erl delete mode 100644 src/jwtf/test/jwtf_tests.erl delete mode 100644 src/ken/README.md delete mode 100644 src/ken/rebar.config.script delete mode 100644 src/ken/src/ken.app.src.script delete mode 100644 src/ken/src/ken.erl delete mode 100644 src/ken/src/ken_app.erl delete mode 100644 src/ken/src/ken_event_handler.erl delete mode 100644 src/ken/src/ken_server.erl delete mode 100644 src/ken/src/ken_sup.erl delete mode 100644 src/ken/test/config.ini delete mode 100644 src/ken/test/ken_server_test.erl delete mode 100644 src/mango/.gitignore delete mode 100644 src/mango/LICENSE.txt delete mode 100644 src/mango/README.md delete mode 100644 src/mango/TODO.md delete mode 100644 src/mango/rebar.config.script delete mode 100644 src/mango/requirements.txt delete mode 100644 src/mango/src/mango.app.src delete mode 100644 src/mango/src/mango.hrl delete mode 100644 src/mango/src/mango_app.erl delete mode 100644 src/mango/src/mango_crud.erl delete mode 100644 src/mango/src/mango_cursor.erl delete mode 100644 src/mango/src/mango_cursor.hrl delete mode 100644 src/mango/src/mango_cursor_special.erl delete mode 100644 src/mango/src/mango_cursor_text.erl delete mode 100644 src/mango/src/mango_cursor_view.erl delete mode 100644 src/mango/src/mango_doc.erl delete mode 100644 src/mango/src/mango_epi.erl delete mode 100644 src/mango/src/mango_error.erl delete mode 100644 src/mango/src/mango_execution_stats.erl delete mode 100644 src/mango/src/mango_execution_stats.hrl delete mode 100644 src/mango/src/mango_fields.erl delete mode 100644 src/mango/src/mango_httpd.erl delete mode 100644 src/mango/src/mango_httpd_handlers.erl delete mode 100644 src/mango/src/mango_idx.erl delete mode 100644 src/mango/src/mango_idx.hrl delete mode 100644 src/mango/src/mango_idx_special.erl delete mode 100644 src/mango/src/mango_idx_text.erl delete mode 100644 src/mango/src/mango_idx_view.erl delete mode 100644 src/mango/src/mango_idx_view.hrl delete mode 100644 src/mango/src/mango_json.erl delete mode 100644 src/mango/src/mango_json_bookmark.erl delete mode 100644 src/mango/src/mango_native_proc.erl delete mode 100644 src/mango/src/mango_opts.erl delete mode 100644 src/mango/src/mango_selector.erl delete mode 100644 src/mango/src/mango_selector_text.erl delete mode 100644 src/mango/src/mango_sort.erl delete mode 100644 src/mango/src/mango_sup.erl delete mode 100644 src/mango/src/mango_util.erl delete mode 100644 src/mango/test/01-index-crud-test.py delete mode 100644 src/mango/test/02-basic-find-test.py delete mode 100644 src/mango/test/03-operator-test.py delete mode 100644 src/mango/test/04-key-tests.py delete mode 100644 src/mango/test/05-index-selection-test.py delete mode 100644 src/mango/test/06-basic-text-test.py delete mode 100644 src/mango/test/06-text-default-field-test.py delete mode 100644 src/mango/test/07-text-custom-field-list-test.py delete mode 100644 src/mango/test/08-text-limit-test.py delete mode 100644 src/mango/test/09-text-sort-test.py delete mode 100644 src/mango/test/10-disable-array-length-field-test.py delete mode 100644 src/mango/test/11-ignore-design-docs-test.py delete mode 100644 src/mango/test/12-use-correct-index-test.py delete mode 100644 src/mango/test/13-stable-update-test.py delete mode 100644 src/mango/test/13-users-db-find-test.py delete mode 100644 src/mango/test/14-json-pagination-test.py delete mode 100644 src/mango/test/15-execution-stats-test.py delete mode 100644 src/mango/test/16-index-selectors-test.py delete mode 100644 src/mango/test/17-multi-type-value-test.py delete mode 100644 src/mango/test/18-json-sort.py delete mode 100644 src/mango/test/19-find-conflicts.py delete mode 100644 src/mango/test/20-no-timeout-test.py delete mode 100644 src/mango/test/21-empty-selector-tests.py delete mode 100644 src/mango/test/README.md delete mode 100644 src/mango/test/friend_docs.py delete mode 100644 src/mango/test/limit_docs.py delete mode 100644 src/mango/test/mango.py delete mode 100644 src/mango/test/user_docs.py delete mode 100644 src/mango/unittest.cfg delete mode 100644 src/mem3/LICENSE delete mode 100644 src/mem3/README.md delete mode 100644 src/mem3/README_reshard.md delete mode 100644 src/mem3/include/mem3.hrl delete mode 100644 src/mem3/priv/stats_descriptions.cfg delete mode 100644 src/mem3/rebar.config delete mode 100644 src/mem3/rebar.config.script delete mode 100644 src/mem3/src/mem3.app.src delete mode 100644 src/mem3/src/mem3.erl delete mode 100644 src/mem3/src/mem3_app.erl delete mode 100644 src/mem3/src/mem3_bdu.erl delete mode 100644 src/mem3/src/mem3_cluster.erl delete mode 100644 src/mem3/src/mem3_epi.erl delete mode 100644 src/mem3/src/mem3_hash.erl delete mode 100644 src/mem3/src/mem3_httpd.erl delete mode 100644 src/mem3/src/mem3_httpd_handlers.erl delete mode 100644 src/mem3/src/mem3_nodes.erl delete mode 100644 src/mem3/src/mem3_plugin_couch_db.erl delete mode 100644 src/mem3/src/mem3_rep.erl delete mode 100644 src/mem3/src/mem3_reshard.erl delete mode 100644 src/mem3/src/mem3_reshard.hrl delete mode 100644 src/mem3/src/mem3_reshard_api.erl delete mode 100644 src/mem3/src/mem3_reshard_dbdoc.erl delete mode 100644 src/mem3/src/mem3_reshard_httpd.erl delete mode 100644 src/mem3/src/mem3_reshard_index.erl delete mode 100644 src/mem3/src/mem3_reshard_job.erl delete mode 100644 src/mem3/src/mem3_reshard_job_sup.erl delete mode 100644 src/mem3/src/mem3_reshard_store.erl delete mode 100644 src/mem3/src/mem3_reshard_sup.erl delete mode 100644 src/mem3/src/mem3_reshard_validate.erl delete mode 100644 src/mem3/src/mem3_rpc.erl delete mode 100644 src/mem3/src/mem3_seeds.erl delete mode 100644 src/mem3/src/mem3_shards.erl delete mode 100644 src/mem3/src/mem3_sup.erl delete mode 100644 src/mem3/src/mem3_sync.erl delete mode 100644 src/mem3/src/mem3_sync_event.erl delete mode 100644 src/mem3/src/mem3_sync_event_listener.erl delete mode 100644 src/mem3/src/mem3_sync_nodes.erl delete mode 100644 src/mem3/src/mem3_sync_security.erl delete mode 100644 src/mem3/src/mem3_util.erl delete mode 100644 src/mem3/test/eunit/mem3_bdu_test.erl delete mode 100644 src/mem3/test/eunit/mem3_cluster_test.erl delete mode 100644 src/mem3/test/eunit/mem3_hash_test.erl delete mode 100644 src/mem3/test/eunit/mem3_rep_test.erl delete mode 100644 src/mem3/test/eunit/mem3_reshard_api_test.erl delete mode 100644 src/mem3/test/eunit/mem3_reshard_changes_feed_test.erl delete mode 100644 src/mem3/test/eunit/mem3_reshard_test.erl delete mode 100644 src/mem3/test/eunit/mem3_ring_prop_tests.erl delete mode 100644 src/mem3/test/eunit/mem3_seeds_test.erl delete mode 100644 src/mem3/test/eunit/mem3_shards_test.erl delete mode 100644 src/mem3/test/eunit/mem3_sync_security_test.erl delete mode 100644 src/mem3/test/eunit/mem3_util_test.erl delete mode 100644 src/rexi/README.md delete mode 100644 src/rexi/include/rexi.hrl delete mode 100644 src/rexi/priv/stats_descriptions.cfg delete mode 100644 src/rexi/rebar.config delete mode 100644 src/rexi/src/rexi.app.src delete mode 100644 src/rexi/src/rexi.erl delete mode 100644 src/rexi/src/rexi_app.erl delete mode 100644 src/rexi/src/rexi_buffer.erl delete mode 100644 src/rexi/src/rexi_monitor.erl delete mode 100644 src/rexi/src/rexi_server.erl delete mode 100644 src/rexi/src/rexi_server_mon.erl delete mode 100644 src/rexi/src/rexi_server_sup.erl delete mode 100644 src/rexi/src/rexi_sup.erl delete mode 100644 src/rexi/src/rexi_utils.erl delete mode 100644 src/setup/.gitignore delete mode 100644 src/setup/LICENSE delete mode 100644 src/setup/README.md delete mode 100644 src/setup/src/setup.app.src delete mode 100644 src/setup/src/setup.erl delete mode 100644 src/setup/src/setup_app.erl delete mode 100644 src/setup/src/setup_epi.erl delete mode 100644 src/setup/src/setup_httpd.erl delete mode 100644 src/setup/src/setup_httpd_handlers.erl delete mode 100644 src/setup/src/setup_sup.erl delete mode 100755 src/setup/test/t-frontend-setup.sh delete mode 100755 src/setup/test/t-single-node-auto-setup.sh delete mode 100755 src/setup/test/t-single-node.sh delete mode 100755 src/setup/test/t.sh delete mode 100644 src/smoosh/README.md delete mode 100644 src/smoosh/operator_guide.md delete mode 100644 src/smoosh/rebar.config delete mode 100644 src/smoosh/recovery_process_diagram.jpeg delete mode 100644 src/smoosh/src/smoosh.app.src delete mode 100644 src/smoosh/src/smoosh.erl delete mode 100644 src/smoosh/src/smoosh_app.erl delete mode 100644 src/smoosh/src/smoosh_channel.erl delete mode 100644 src/smoosh/src/smoosh_priority_queue.erl delete mode 100644 src/smoosh/src/smoosh_server.erl delete mode 100644 src/smoosh/src/smoosh_sup.erl delete mode 100644 src/smoosh/src/smoosh_utils.erl delete mode 100644 src/smoosh/test/exunit/scheduling_window_test.exs delete mode 100644 src/smoosh/test/exunit/test_helper.exs delete mode 100644 src/smoosh/test/smoosh_priority_queue_tests.erl delete mode 100644 src/smoosh/test/smoosh_tests.erl delete mode 100644 src/weatherreport/.gitignore delete mode 100644 src/weatherreport/.manifest delete mode 100644 src/weatherreport/LICENSE delete mode 100644 src/weatherreport/README.md delete mode 100644 src/weatherreport/how_to_add_a_check.md delete mode 100644 src/weatherreport/rebar.config delete mode 100644 src/weatherreport/src/weatherreport.app.src delete mode 100644 src/weatherreport/src/weatherreport.erl delete mode 100644 src/weatherreport/src/weatherreport_check.erl delete mode 100644 src/weatherreport/src/weatherreport_check_custodian.erl delete mode 100644 src/weatherreport/src/weatherreport_check_disk.erl delete mode 100644 src/weatherreport/src/weatherreport_check_internal_replication.erl delete mode 100644 src/weatherreport/src/weatherreport_check_ioq.erl delete mode 100644 src/weatherreport/src/weatherreport_check_mem3_sync.erl delete mode 100644 src/weatherreport/src/weatherreport_check_membership.erl delete mode 100644 src/weatherreport/src/weatherreport_check_memory_use.erl delete mode 100644 src/weatherreport/src/weatherreport_check_message_queues.erl delete mode 100644 src/weatherreport/src/weatherreport_check_node_stats.erl delete mode 100644 src/weatherreport/src/weatherreport_check_nodes_connected.erl delete mode 100644 src/weatherreport/src/weatherreport_check_process_calls.erl delete mode 100644 src/weatherreport/src/weatherreport_check_process_memory.erl delete mode 100644 src/weatherreport/src/weatherreport_check_safe_to_rebuild.erl delete mode 100644 src/weatherreport/src/weatherreport_check_search.erl delete mode 100644 src/weatherreport/src/weatherreport_check_tcp_queues.erl delete mode 100644 src/weatherreport/src/weatherreport_config.erl delete mode 100644 src/weatherreport/src/weatherreport_getopt.erl delete mode 100644 src/weatherreport/src/weatherreport_log.erl delete mode 100644 src/weatherreport/src/weatherreport_node.erl delete mode 100644 src/weatherreport/src/weatherreport_runner.erl delete mode 100644 src/weatherreport/src/weatherreport_util.erl delete mode 100644 support/build_js.escript delete mode 100755 test/bench/benchbulk.sh delete mode 100755 test/build/test-configure-distclean.sh delete mode 100755 test/build/test-configure.sh delete mode 100755 test/build/test-make-clean.sh delete mode 100644 test/elixir/.formatter.exs delete mode 100644 test/elixir/.gitignore delete mode 100644 test/elixir/Makefile delete mode 100644 test/elixir/README.md delete mode 100644 test/elixir/config/config.exs delete mode 100644 test/elixir/config/test.exs delete mode 100644 test/elixir/lib/couch.ex delete mode 100644 test/elixir/lib/couch/db_test.ex delete mode 100644 test/elixir/lib/couch_raw.ex delete mode 100644 test/elixir/lib/ex_unit.ex delete mode 100644 test/elixir/lib/setup.ex delete mode 100644 test/elixir/lib/setup/common.ex delete mode 100644 test/elixir/lib/step.ex delete mode 100644 test/elixir/lib/step/config.ex delete mode 100644 test/elixir/lib/step/create_db.ex delete mode 100644 test/elixir/lib/step/start.ex delete mode 100644 test/elixir/lib/step/user.ex delete mode 100644 test/elixir/lib/suite.ex delete mode 100644 test/elixir/lib/utils.ex delete mode 100644 test/elixir/run.cmd delete mode 100644 test/elixir/test/all_docs_test.exs delete mode 100644 test/elixir/test/attachment_names_test.exs delete mode 100644 test/elixir/test/attachment_paths_test.exs delete mode 100644 test/elixir/test/attachment_ranges_test.exs delete mode 100644 test/elixir/test/attachment_views_test.exs delete mode 100644 test/elixir/test/attachments_multipart_test.exs delete mode 100644 test/elixir/test/attachments_test.exs delete mode 100644 test/elixir/test/auth_cache_test.exs delete mode 100644 test/elixir/test/basics_test.exs delete mode 100644 test/elixir/test/batch_save_test.exs delete mode 100644 test/elixir/test/bulk_docs_test.exs delete mode 100644 test/elixir/test/changes_async_test.exs delete mode 100644 test/elixir/test/changes_test.exs delete mode 100644 test/elixir/test/cluster_with_quorum_test.exs delete mode 100644 test/elixir/test/cluster_without_quorum_test.exs delete mode 100644 test/elixir/test/coffee_test.exs delete mode 100644 test/elixir/test/compact_test.exs delete mode 100644 test/elixir/test/config/skip.elixir delete mode 100644 test/elixir/test/config/suite.elixir delete mode 100644 test/elixir/test/config/test-config.ini delete mode 100644 test/elixir/test/config_test.exs delete mode 100644 test/elixir/test/conflicts_test.exs delete mode 100644 test/elixir/test/cookie_auth_test.exs delete mode 100644 test/elixir/test/copy_doc_test.exs delete mode 100644 test/elixir/test/data/lorem.txt delete mode 100644 test/elixir/test/data/lorem_b64.txt delete mode 100644 test/elixir/test/design_docs_query_test.exs delete mode 100644 test/elixir/test/design_docs_test.exs delete mode 100644 test/elixir/test/design_options_test.exs delete mode 100644 test/elixir/test/design_paths_test.exs delete mode 100644 test/elixir/test/erlang_views_test.exs delete mode 100644 test/elixir/test/etags_head_test.exs delete mode 100644 test/elixir/test/form_submit_test.exs delete mode 100644 test/elixir/test/helper_test.exs delete mode 100644 test/elixir/test/http_test.exs delete mode 100644 test/elixir/test/invalid_docids_test.exs delete mode 100644 test/elixir/test/jsonp_test.exs delete mode 100644 test/elixir/test/jwtauth_test.exs delete mode 100644 test/elixir/test/large_docs_text.exs delete mode 100644 test/elixir/test/list_views_test.exs delete mode 100644 test/elixir/test/local_docs_test.exs delete mode 100644 test/elixir/test/lots_of_docs_test.exs delete mode 100644 test/elixir/test/method_override_test.exs delete mode 100644 test/elixir/test/multiple_rows_test.exs delete mode 100644 test/elixir/test/partition_all_docs_test.exs delete mode 100644 test/elixir/test/partition_crud_test.exs delete mode 100644 test/elixir/test/partition_ddoc_test.exs delete mode 100644 test/elixir/test/partition_design_docs_test.exs delete mode 100644 test/elixir/test/partition_helpers.exs delete mode 100644 test/elixir/test/partition_mango_test.exs delete mode 100644 test/elixir/test/partition_size_limit_test.exs delete mode 100644 test/elixir/test/partition_size_test.exs delete mode 100644 test/elixir/test/partition_view_test.exs delete mode 100644 test/elixir/test/partition_view_update_test.exs delete mode 100644 test/elixir/test/proxyauth_test.exs delete mode 100644 test/elixir/test/purge_test.exs delete mode 100644 test/elixir/test/reader_acl_test.exs delete mode 100644 test/elixir/test/recreate_doc_test.exs delete mode 100644 test/elixir/test/reduce_builtin_test.exs delete mode 100644 test/elixir/test/reduce_false_test.exs delete mode 100644 test/elixir/test/reduce_test.exs delete mode 100644 test/elixir/test/replication_test.exs delete mode 100644 test/elixir/test/reshard_all_docs_test.exs delete mode 100644 test/elixir/test/reshard_basic_test.exs delete mode 100644 test/elixir/test/reshard_changes_feed.exs delete mode 100644 test/elixir/test/reshard_helpers.exs delete mode 100644 test/elixir/test/rev_stemming_test.exs delete mode 100644 test/elixir/test/rewrite_js_test.exs delete mode 100644 test/elixir/test/rewrite_test.exs delete mode 100644 test/elixir/test/security_validation_test.exs delete mode 100644 test/elixir/test/show_documents_test.exs delete mode 100644 test/elixir/test/support/couch_test_case.ex delete mode 100644 test/elixir/test/test_helper.exs delete mode 100644 test/elixir/test/update_documents_test.exs delete mode 100644 test/elixir/test/users_db_security_test.exs delete mode 100644 test/elixir/test/users_db_test.exs delete mode 100644 test/elixir/test/utf8_test.exs delete mode 100644 test/elixir/test/uuids_test.exs delete mode 100644 test/elixir/test/view_collation_raw_test.exs delete mode 100644 test/elixir/test/view_collation_test.exs delete mode 100644 test/elixir/test/view_compaction_test.exs delete mode 100644 test/elixir/test/view_conflicts_test.exs delete mode 100644 test/elixir/test/view_errors_test.exs delete mode 100644 test/elixir/test/view_include_docs_test.exs delete mode 100644 test/elixir/test/view_multi_key_all_docs_test.exs delete mode 100644 test/elixir/test/view_multi_key_design_test.exs delete mode 100644 test/elixir/test/view_offsets_test.exs delete mode 100644 test/elixir/test/view_pagination_test.exs delete mode 100644 test/elixir/test/view_sandboxing_test.exs delete mode 100644 test/elixir/test/view_test.exs delete mode 100644 test/elixir/test/view_update_seq_test.exs delete mode 100644 test/javascript/tests/list_views.js delete mode 100644 test/javascript/tests/proxyauth.js delete mode 100644 test/javascript/tests/replicator_db_bad_rep_id.js delete mode 100644 test/javascript/tests/replicator_db_by_doc_id.js delete mode 100644 test/javascript/tests/rewrite.js delete mode 100644 test/javascript/tests/rewrite_js.js delete mode 100644 test/javascript/tests/security_validation.js delete mode 100644 test/javascript/tests/show_documents.js delete mode 100644 test/javascript/tests/users_db_security.js delete mode 100644 test/random_port.ini delete mode 100644 test/view_server/query_server_spec.rb delete mode 100755 test/view_server/run_native_process.es delete mode 100644 version.mk diff --git a/.credo.exs b/.credo.exs deleted file mode 100644 index 59e5550fe..000000000 --- a/.credo.exs +++ /dev/null @@ -1,174 +0,0 @@ -# This file contains the configuration for Credo and you are probably reading -# this after creating it with `mix credo.gen.config`. -# -# If you find anything wrong or unclear in this file, please report an -# issue on GitHub: https://github.com/rrrene/credo/issues -# -%{ - # - # You can have as many configs as you like in the `configs:` field. - configs: [ - %{ - # - # Run any exec using `mix credo -C `. If no exec name is given - # "default" is used. - # - name: "default", - # - # These are the files included in the analysis: - files: %{ - # - # You can give explicit globs or simply directories. - # In the latter case `**/*.{ex,exs}` will be used. - # - included: ["lib/", "src/", "test/", "web/", "apps/"], - excluded: [ - ~r"/_build/", - ~r"/node_modules/", - ~r"/src/certifi/", - ~r"/src/excoveralls/", - ~r"/src/jason", - ~r"/src/hackney", - ~r"/src/httpotion", - ~r"/src/file_system", - ~r"/src/credo", - ~r"/src/idna", - ~r"/src/junit_formatter", - ~r"/src/bunt", - ~r"/src/metrics", - ~r"/src/minerl", - ~r"/src/parse_trans", - ~r"/src/ssl_verify_fun", - ~r"/test/elixir/deps/" - ] - }, - # - # If you create your own checks, you must specify the source files for - # them here, so they can be loaded by Credo before running the analysis. - # - requires: [], - # - # If you want to enforce a style guide and need a more traditional linting - # experience, you can change `strict` to `true` below: - # - strict: false, - # - # If you want to use uncolored output by default, you can change `color` - # to `false` below: - # - color: true, - # - # You can customize the parameters of any check by adding a second element - # to the tuple. - # - # To disable a check put `false` as second element: - # - # {Credo.Check.Design.DuplicatedCode, false} - # - checks: [ - # - ## Consistency Checks - # - {Credo.Check.Consistency.ExceptionNames, []}, - {Credo.Check.Consistency.LineEndings, []}, - {Credo.Check.Consistency.ParameterPatternMatching, false}, - {Credo.Check.Consistency.SpaceAroundOperators, []}, - {Credo.Check.Consistency.SpaceInParentheses, []}, - {Credo.Check.Consistency.TabsOrSpaces, []}, - - # - ## Design Checks - # - # You can customize the priority of any check - # Priority values are: `low, normal, high, higher` - # - {Credo.Check.Design.AliasUsage, - [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]}, - # You can also customize the exit_status of each check. - # If you don't want TODO comments to cause `mix credo` to fail, just - # set this value to 0 (zero). - # - {Credo.Check.Design.TagTODO, false}, - {Credo.Check.Design.TagFIXME, []}, - - # - ## Readability Checks - # - {Credo.Check.Readability.AliasOrder, []}, - {Credo.Check.Readability.FunctionNames, []}, - {Credo.Check.Readability.LargeNumbers, []}, - {Credo.Check.Readability.MaxLineLength, [priority: :normal, max_length: 90]}, - {Credo.Check.Readability.ModuleAttributeNames, []}, - {Credo.Check.Readability.ModuleDoc, []}, - {Credo.Check.Readability.ModuleNames, []}, - {Credo.Check.Readability.ParenthesesInCondition, []}, - {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []}, - {Credo.Check.Readability.PredicateFunctionNames, []}, - {Credo.Check.Readability.PreferImplicitTry, []}, - {Credo.Check.Readability.RedundantBlankLines, []}, - {Credo.Check.Readability.Semicolons, []}, - {Credo.Check.Readability.SpaceAfterCommas, []}, - {Credo.Check.Readability.StringSigils, []}, - {Credo.Check.Readability.TrailingBlankLine, []}, - {Credo.Check.Readability.TrailingWhiteSpace, []}, - {Credo.Check.Readability.VariableNames, []}, - - # - ## Refactoring Opportunities - # - {Credo.Check.Refactor.CondStatements, []}, - {Credo.Check.Refactor.CyclomaticComplexity, false}, - {Credo.Check.Refactor.FunctionArity, []}, - {Credo.Check.Refactor.LongQuoteBlocks, false}, - {Credo.Check.Refactor.MapInto, []}, - {Credo.Check.Refactor.MatchInCondition, []}, - {Credo.Check.Refactor.NegatedConditionsInUnless, []}, - {Credo.Check.Refactor.NegatedConditionsWithElse, []}, - {Credo.Check.Refactor.Nesting, false}, - {Credo.Check.Refactor.PipeChainStart, - [ - excluded_argument_types: [:atom, :binary, :fn, :keyword], - excluded_functions: [] - ]}, - {Credo.Check.Refactor.UnlessWithElse, []}, - - # - ## Warnings - # - {Credo.Check.Warning.BoolOperationOnSameValues, []}, - {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []}, - {Credo.Check.Warning.IExPry, []}, - {Credo.Check.Warning.IoInspect, []}, - {Credo.Check.Warning.LazyLogging, []}, - {Credo.Check.Warning.OperationOnSameValues, []}, - {Credo.Check.Warning.OperationWithConstantResult, []}, - {Credo.Check.Warning.RaiseInsideRescue, []}, - {Credo.Check.Warning.UnusedEnumOperation, []}, - {Credo.Check.Warning.UnusedFileOperation, []}, - {Credo.Check.Warning.UnusedKeywordOperation, []}, - {Credo.Check.Warning.UnusedListOperation, []}, - {Credo.Check.Warning.UnusedPathOperation, []}, - {Credo.Check.Warning.UnusedRegexOperation, []}, - {Credo.Check.Warning.UnusedStringOperation, []}, - {Credo.Check.Warning.UnusedTupleOperation, []}, - - # - # Controversial and experimental checks (opt-in, just remove `, false`) - # - {Credo.Check.Consistency.MultiAliasImportRequireUse, false}, - {Credo.Check.Design.DuplicatedCode, false}, - {Credo.Check.Readability.Specs, false}, - {Credo.Check.Refactor.ABCSize, false}, - {Credo.Check.Refactor.AppendSingleItem, false}, - {Credo.Check.Refactor.DoubleBooleanNegation, false}, - {Credo.Check.Refactor.VariableRebinding, false}, - {Credo.Check.Warning.MapGetUnsafePass, false}, - {Credo.Check.Warning.UnsafeToAtom, false} - - # - # Custom checks can be created using `mix credo.gen.check`. - # - ] - } - ] -} diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 04a117cb2..000000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,24 +0,0 @@ -ARG ELIXIR_VERSION -FROM elixir:${ELIXIR_VERSION} - -# Install SpiderMonkey 60 and tell CouchDB to use it in configure -ENV SM_VSN=60 - -# Use NodeSource binaries for Node.js (Fauxton dependency) -RUN set -ex; \ - curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add -; \ - echo "deb https://deb.nodesource.com/node_10.x buster main" | tee /etc/apt/sources.list.d/nodesource.list; \ - echo "deb-src https://deb.nodesource.com/node_10.x buster main" | tee -a /etc/apt/sources.list.d/nodesource.list - -RUN set -ex; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ - libmozjs-${SM_VSN}-dev \ - libicu-dev \ - python3-venv \ - python3-pip \ - python3-sphinx \ - nodejs - -# Documentation theme -RUN pip3 install sphinx_rtd_theme diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 666f9fa16..000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "build": { - "dockerfile": "Dockerfile", - "args": { - // Useful choices include: - // 1.11 -> Erlang 23, Debian Buster - // 1.10 -> Erlang 22, Debian Buster - // 1.9 -> Erlang 22, Debian Buster - // - // Older versions based on Debian Stretch will not include - // SpiderMonkey 60, which the Dockerfile expects to be able - // to install via apt-get. - "ELIXIR_VERSION": "1.10" - } - }, - "extensions": [ - "erlang-ls.erlang-ls" - ] -} diff --git a/.formatter.exs b/.formatter.exs deleted file mode 100644 index 28b883d54..000000000 --- a/.formatter.exs +++ /dev/null @@ -1,9 +0,0 @@ -# Used by "mix format" -[ - inputs: [ - "{mix,.formatter}.exs", - "{config,src}/*/test/exunit/*.{ex,exs}" - ], - line_length: 90, - rename_deprecated_at: "1.5.0" -] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 360d4fa62..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Describe a scenario in which CouchDB behaves unexpectedly -title: '' -labels: bug, needs-triage -assignees: '' - ---- - -[NOTE]: # ( ^^ Provide a general summary of the issue in the title above. ^^ ) - -## Description - -[NOTE]: # ( Describe the problem you're encountering. ) -[TIP]: # ( Do NOT give us access or passwords to your actual CouchDB! ) - -## Steps to Reproduce - -[NOTE]: # ( Include commands to reproduce, if possible. curl is preferred. ) - -## Expected Behaviour - -[NOTE]: # ( Tell us what you expected to happen. ) - -## Your Environment - -[TIP]: # ( Include as many relevant details about your environment as possible. ) -[TIP]: # ( You can paste the output of curl http://YOUR-COUCHDB:5984/ here. ) - -* CouchDB version used: -* Browser name and version: -* Operating system and version: - -## Additional Context - -[TIP]: # ( Add any other context about the problem here. ) diff --git a/.github/ISSUE_TEMPLATE/enhancement.md b/.github/ISSUE_TEMPLATE/enhancement.md deleted file mode 100644 index ca92725a6..000000000 --- a/.github/ISSUE_TEMPLATE/enhancement.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Enhancement request -about: Suggest an idea for a future version of CouchDB -title: '' -labels: enhancement, needs-triage -assignees: '' - ---- - -[NOTE]: # ( ^^ Provide a general summary of the request in the title above. ^^ ) - -## Summary - -[NOTE]: # ( Provide a brief overview of what the new feature is all about. ) - -## Desired Behaviour - -[NOTE]: # ( Tell us how the new feature should work. Be specific. ) -[TIP]: # ( Do NOT give us access or passwords to your actual CouchDB! ) - -## Possible Solution - -[NOTE]: # ( Not required. Suggest how to implement the addition or change. ) - -## Additional context - -[TIP]: # ( Why does this feature matter to you? What unique circumstances do you have? ) diff --git a/.github/ISSUE_TEMPLATE/rfc.md b/.github/ISSUE_TEMPLATE/rfc.md deleted file mode 100644 index 08bd0549e..000000000 --- a/.github/ISSUE_TEMPLATE/rfc.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -name: Formal RFC -about: Submit a formal Request For Comments for consideration by the team. -title: '' -labels: rfc, discussion -assignees: '' - ---- - -[NOTE]: # ( ^^ Provide a general summary of the RFC in the title above. ^^ ) - -# Introduction - -## Abstract - -[NOTE]: # ( Provide a 1-to-3 paragraph overview of the requested change. ) -[NOTE]: # ( Describe what problem you are solving, and the general approach. ) - -## Requirements Language - -[NOTE]: # ( Do not alter the section below. Follow its instructions. ) - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", -"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this -document are to be interpreted as described in -[RFC 2119](https://www.rfc-editor.org/rfc/rfc2119.txt). - -## Terminology - -[TIP]: # ( Provide a list of any unique terms or acronyms, and their definitions here.) - ---- - -# Detailed Description - -[NOTE]: # ( Describe the solution being proposed in greater detail. ) -[NOTE]: # ( Assume your audience has knowledge of, but not necessarily familiarity ) -[NOTE]: # ( with, the CouchDB internals. Provide enough context so that the reader ) -[NOTE]: # ( can make an informed decision about the proposal. ) - -[TIP]: # ( Artwork may be attached to the submission and linked as necessary. ) -[TIP]: # ( ASCII artwork can also be included in code blocks, if desired. ) - -# Advantages and Disadvantages - -[NOTE]: # ( Briefly, list the benefits and drawbacks that would be realized should ) -[NOTE]: # ( the proposal be accepted for inclusion into Apache CouchDB. ) - -# Key Changes - -[TIP]: # ( If the changes will affect how a user interacts with CouchDB, explain. ) - -## Applications and Modules affected - -[NOTE]: # ( List the OTP applications or functional modules in CouchDB affected by the proposal. ) - -## HTTP API additions - -[NOTE]: # ( Provide *exact* detail on each new API endpoint, including: ) -[NOTE]: # ( HTTP methods [HEAD, GET, PUT, POST, DELETE, etc.] ) -[NOTE]: # ( Synopsis of functionality ) -[NOTE]: # ( Headers and parameters accepted ) -[NOTE]: # ( JSON in [if a PUT or POST type] ) -[NOTE]: # ( JSON out ) -[NOTE]: # ( Valid status codes and their defintions ) -[NOTE]: # ( A proposed Request and Response block ) - -## HTTP API deprecations - -[NOTE]: # ( Provide *exact* detail on the API endpoints to be deprecated. ) -[NOTE]: # ( If these endpoints are replaced by new endpoints, list those as well. ) -[NOTE]: # ( State the proposed version in which the deprecation and removal will occur. ) - -# Security Considerations - -[NOTE]: # ( Include any impact to the security of CouchDB here. ) - -# References - -[TIP]: # ( Include any references to CouchDB documentation, mailing list discussion, ) -[TIP]: # ( external standards or other links here. ) - -# Acknowledgements - -[TIP]: # ( Who helped you write this RFC? ) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 0d3aef603..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,35 +0,0 @@ - - -## Overview - - - -## Testing recommendations - - - -## Related Issues or Pull Requests - - - -## Checklist - -- [ ] Code is written and works correctly -- [ ] Changes are covered by tests -- [ ] Any new configurable parameters are documented in `rel/overlay/etc/default.ini` -- [ ] A PR for documentation changes has been made in https://github.com/apache/couchdb-documentation diff --git a/.gitignore b/.gitignore deleted file mode 100644 index dd3cb9442..000000000 --- a/.gitignore +++ /dev/null @@ -1,132 +0,0 @@ -*.o -*.asc -*.sha256 -*.sha512 -*.snap -*.so -*.pyc -*.swp -*.pdb -*~ -.venv -.DS_Store -.vscode -.rebar/ -.eunit/ -cover/ -core -debian/ -log -apache-couchdb-*/ -bin/ -config.erl -*.tar.gz -*.tar.bz2 -dev/*.beam -dev/devnode.* -dev/lib/ -dev/logs/ -dev/erlserver.pem -dev/couch_ssl_dist.conf -ebin/ -erl_crash.dump -erln8.config -install.mk -rel/*.config -rel/couchdb -rel/dev* -rel/tmpdata -share/server/main-coffee.js -share/server/main.js -share/www -src/b64url/ -src/bear/ -src/certifi/ -src/config/ -src/couch/priv/couch_js/**/config.h -src/couch/priv/couchjs -src/couch/priv/couchspawnkillable -src/couch/priv/couch_ejson_compare/couch_ejson_compare.d -src/couch/priv/couch_js/**/*.d -src/couch/priv/icu_driver/couch_icu_driver.d -src/mango/src/mango_cursor_text.nocompile -src/docs/ -src/ets_lru/ -src/excoveralls/ -src/fauxton/ -src/folsom/ -src/hackney/ -src/hqueue/ -src/hyper/ -src/ibrowse/ -src/idna/ -src/jiffy/ -src/khash/ -src/meck/ -src/metrics/ -src/mimerl/ -src/mochiweb/ -src/oauth/ -src/parse_trans/ -src/proper/ -src/rebar/ -src/recon/ -src/snappy/ -src/ssl_verify_fun/ -src/triq/ -src/unicode_util_compat/ -src/file_system/ -src/rebar3/ -src/erlfmt/ -tmp/ - -src/couch/*.o -src/couch/*.so -src/couch/ebin/ -src/couch/priv/couch_js/config.h -src/couch/priv/couchjs -src/couch/priv/couchspawnkillable -src/couch/priv/*.exp -src/couch/priv/*.lib -src/couch/priv/*.dll -src/couch/priv/*.exe -src/couch/vc120.pdb -src/couch_epi/ebin -src/couch_epi/erl_crash.dump -src/couch_event/deps/ -src/couch_event/ebin/ -src/couch_index/ebin -src/couch_log/ebin -src/couch_peruser/doc -src/couch_peruser/ebin -src/couch_peruser/deps -src/couch_peruser/couchperuser-* -src/couch_peruser/erl_crash.dump -src/couch_peruser/TEST-*.xml -src/couch_peruser/*.beam -src/couch_replicator/*.beam -src/couch_replicator/ebin/replicator.app -src/couch_replicator/.DS_Store -src/couch_stats/*~ -src/couch_stats/*.beam -src/couch_stats/deps -src/couch_stats/ebin -src/couch_stats/doc -src/couch_stats/.project -src/couch_tests/*.o -src/couch_tests/*.so -src/couch_tests/ebin/ -src/global_changes/ebin/ -src/mango/ebin/ -src/mango/test/*.pyc -src/mango/nosetests.xml -src/mango/venv/ -src/jwtf/.rebar3/ -test/javascript/junit.xml - -/_build/ -/src/bunt -/src/credo/ -/src/httpotion/ -/src/jason/ -/src/junit_formatter/ diff --git a/.mailmap b/.mailmap deleted file mode 100644 index a51c763dc..000000000 --- a/.mailmap +++ /dev/null @@ -1,13 +0,0 @@ -Benoit Chesneau -Benoit Chesneau benoitc - -Jason Smith Jason Smith (air) -Jason Smith Jason Smith (air) - -Filipe David Borba Manana - -Randall Leeds - -Paul Joseph Davis Paul J. Davis - -Bob Dionne bitdiddle diff --git a/BUGS.md b/BUGS.md deleted file mode 100644 index 235b634d6..000000000 --- a/BUGS.md +++ /dev/null @@ -1,13 +0,0 @@ -Apache CouchDB BUGS -=================== - -Visit our issue tracker: - - https://github.com/apache/couchdb/issues - -You can use this to report bugs, request features, or suggest enhancements. - -Our JIRA system no longer accepts new issues, but may have important historical -information: - - https://issues.apache.org/jira/browse/CouchDB diff --git a/COMMITTERS.md b/COMMITTERS.md deleted file mode 100644 index 3b25283e3..000000000 --- a/COMMITTERS.md +++ /dev/null @@ -1,11 +0,0 @@ -Apache CouchDB COMMITTERS -========================= - -Committers are given a binding vote in certain project decisions, as well as -write access to public project infrastructure. Committers are elected to the -project in recognition of their committment to Apache CouchDB. We mean this in -the sense of being loyal to the project and its interests. - -A full list of committers elected to the project is available at: - - https://people.apache.org/committers-by-project.html#couchdb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index cd3a4437c..000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,290 +0,0 @@ -# Contributing to CouchDB - -Please take a moment to review this document in order to make the contribution -process easy and effective for everyone involved. - -Following these guidelines helps to communicate that you respect the time of -the developers managing and developing this open source project. In return, -they should reciprocate that respect in addressing your issue, assessing -changes, and helping you finalize your pull requests. - -Contributions to CouchDB are governed by our [Code of Conduct][6] and a set of -[Project Bylaws][7]. Come join us! - - -## Using the issue tracker - -First things first: **Do NOT report security vulnerabilities in public issues!** -Please disclose responsibly by letting [the Apache CouchDB Security team](mailto:security@couchdb.apache.org?subject=Security) -know upfront. We will assess the issue as soon as possible on a best-effort -basis and will give you an estimate for when we have a fix and release available -for an eventual public disclosure. - -The GitHub issue tracker is the preferred channel for [bug reports](#bugs), -[features requests](#features) and [submitting pull requests](#pull-requests), -but please respect the following restrictions: - -* Please **do not** use the issue tracker for personal support requests. Use - [CouchDB Chat][8] instead. Alternately, help us to help more people by - using our publicly archived [user][1] or [developer][5] mailing lists. - -* Please **do not** derail or troll issues. Keep the discussion on topic and - respect the opinions of others. - - -## Bug reports - -A bug is a _demonstrable problem_ that is caused by the code in our -repositories. Good bug reports are extremely helpful - thank you! - -Guidelines for bug reports: - -1. **Use the GitHub issue search** — check if the issue has already been - reported. - -2. **Check if the issue has been fixed** — try to reproduce it using the - latest `master` or `next` branch in the repository. - -3. **Isolate the problem** — ideally create a reduced test case. - -A good bug report shouldn't leave others needing to chase you up for more -information. Please try to be as detailed as possible in your report. What is -your environment? What steps will reproduce the issue? What OS experiences the -problem? What would you expect to be the outcome? All these details will help -people to fix any potential bugs. Our issue template will help you include all -of the relevant detail. - -Example: - -> Short and descriptive example bug report title -> -> A summary of the issue and the browser/OS environment in which it occurs. If -> suitable, include the steps required to reproduce the bug. -> -> 1. This is the first step -> 2. This is the second step -> 3. Further steps, etc. -> -> `` - a link to the reduced test case -> -> Any other information you want to share that is relevant to the issue being -> reported. This might include the lines of code that you have identified as -> causing the bug, and potential solutions (and your opinions on their -> merits). - - -## Feature requests - -Feature requests are welcome. But take a moment to find out whether your idea -fits with the scope and aims of the project. It's up to *you* to make a strong -case to convince the project's developers of the merits of this feature. Please -provide as much detail and context as possible. - - -## Pull requests - -Good pull requests - patches, improvements, new features - are a fantastic -help. They should remain focused in scope and avoid containing unrelated -commits. - -**Please ask first** before embarking on any significant pull request (e.g. -implementing features, refactoring code), otherwise you risk spending a lot of -time working on something that the project's developers might not want to merge -into the project. You can talk with the community on our -[developer mailing list][5]. We're always open to suggestions and will get -back to you as soon as we can! - - -### For new Contributors - -If you never created a pull request before, welcome :tada: :smile: [Here is a great tutorial](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) -on how to send one :) - -1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, - and configure the remotes: - - ```bash - # Clone your fork of the repo into the current directory - git clone https://github.com// - # Navigate to the newly cloned directory - cd - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/apache/ - ``` - -2. If you cloned a while ago, get the latest changes from upstream: - - ```bash - git checkout master - git pull upstream master - ``` - -3. Create a new topic branch (off the main project development branch) to - contain your feature, change, or fix: - - ```bash - git checkout -b - ``` - -4. Make sure to update, or add to the tests when appropriate. Patches and - features will not be accepted without tests. Run `make check` to check that - all tests pass after you've made changes. Look for a `Testing` section in - the project’s README for more information. - -5. If you added or changed a feature, make sure to document it accordingly in - the [CouchDB documentation](https://github.com/apache/couchdb-documentation) - repository. - -6. Push your topic branch up to your fork: - - ```bash - git push origin - ``` - -8. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) - with a clear title and description. - - -### For Apache CouchDB Committers - -1. Be sure to set up [GitHub two-factor authentication](https://help.github.com/articles/about-two-factor-authentication/), - then [link your Apache account to your GitHub account](https://gitbox.apache.org/setup/). - You will need to wait about 30 minutes after completing this process - for it to complete. Follow the instructions in the organisational - invite email you receive. Alternately, you can use the Apache mirror - of the repository at `https://gitbox.apache.org/repos/asf/couchdb.git` - if you do not agree to the GitHub Terms of Service. - -2. Clone the repo and create a branch. - - ```bash - git clone https://github.com/couchdb/couchdb - # or git clone https://gitbox.apache.org/repos/asf/couchdb.git - cd couchdb - git checkout -b - ``` - -3. Make sure to update, or add to the tests when appropriate. Patches and - features will not be accepted without tests. Run `make check` to check that - all tests pass after you've made changes. Look for a `Testing` section in - the project’s README for more information. - -4. If you added or changed a feature, make sure to document it accordingly in - the [CouchDB documentation](https://github.com/apache/couchdb-documentation) - repository. - -5. Push your topic branch up to our repo - - ```bash - git push origin - ``` - -6. Open a Pull Request using your branch with a clear title and description. - Please also add any appropriate labels to the pull request for clarity. - -Optionally, you can help us with these things. But don’t worry if they are too -complicated, we can help you out and teach you as we go :) - -1. Update your branch to the latest changes in the upstream master branch. You - can do that locally with - - ```bash - git pull --rebase upstream master - ``` - - Afterwards force push your changes to your remote feature branch. - -2. Once a pull request is good to go, you can tidy up your commit messages using - Git's [interactive rebase](https://help.github.com/articles/interactive-rebase). - -**IMPORTANT**: By submitting a patch, you agree to license your work under the -Apache License, per your signed Apache CLA. - - -## Triagers - -Apache CouchDB committers who have completed the GitHub account linking -process may triage issues. This helps to speed up releases and minimises both -user and developer pain in working through our backlog. - -Briefly, to triage an issue, review the report, validate that it is an actual -issue (reproducing if possible), and add one or more labels. We have a -[summary of our label taxonomy](https://github.com/apache/couchdb/issues/499) -for your reference. - -If you are not an official committer, please reach out to our [mailing list][5] -or [chat][8] to learn how you can assist with triaging indirectly. - - -## Maintainers - -If you have commit access, please follow this process for merging patches and cutting new releases. - -### Reviewing changes - -1. Check that a change is within the scope and philosophy of the component. -2. Check that a change has any necessary tests. -3. Check that a change has any necessary documentation. -4. If there is anything you don’t like, leave a comment below the respective - lines and submit a "Request changes" review. Repeat until everything has - been addressed. -5. If you are not sure about something, mention specific people for help in a - comment. -6. If there is only a tiny change left before you can merge it and you think - it’s best to fix it yourself, you can directly commit to the author’s fork. - Leave a comment about it so the author and others will know. -7. Once everything looks good, add an "Approve" review. Don’t forget to say - something nice 👏🐶💖✨ -8. If the commit messages follow [our conventions](@commit-message-conventions) - - 1. If the pull request fixes one or more open issues, please include the - text "Fixes #472" or "Fixes apache/couchdb#472". - 2. Use the "Rebase and merge" button to merge the pull request. - 3. Done! You are awesome! Thanks so much for your help 🤗 - -9. If the commit messages _do not_ follow our conventions - - 1. Use the "squash and merge" button to clean up the commits and merge at - the same time: ✨🎩 - 2. If the pull request fixes one or more open issues, please include the - text "Fixes #472" or "Fixes apache/couchdb#472". - -Sometimes there might be a good reason to merge changes locally. The process -looks like this: - -### Reviewing and merging changes locally - -``` -git checkout master # or the main branch configured on github -git pull # get latest changes -git checkout feature-branch # replace name with your branch -git rebase master -git checkout master -git merge feature-branch # replace name with your branch -git push -``` - -When merging PRs from forked repositories, we recommend you install the -[hub](https://github.com/github/hub) command line tools. - -This allows you to do: - -``` -hub checkout link-to-pull-request -``` - -meaning that you will automatically check out the branch for the pull request, -without needing any other steps like setting git upstreams! :sparkles: - - -## Thanks - -Special thanks to [Hoodie](https://github.com/hoodiehq/hoodie) for the great -CONTRIBUTING.md template. - -[1]: http://mail-archives.apache.org/mod_mbox/couchdb-user/ -[5]: http://mail-archives.apache.org/mod_mbox/couchdb-dev/ -[6]: http://couchdb.apache.org/conduct.html -[7]: http://couchdb.apache.org/bylaws.html -[8]: http://couchdb.apache.org/#chat - diff --git a/CONTRIBUTORS.in b/CONTRIBUTORS.in deleted file mode 100644 index 6edf71d8c..000000000 --- a/CONTRIBUTORS.in +++ /dev/null @@ -1,97 +0,0 @@ -Apache CouchDB CONTRIBUTORS -=========================== - -A number of people have made contributions to the Apache CouchDB community, -project, documentation, or code. Some of these people are listed here. - - * William Beh - * Dirk Schalge - * Roger Leigh - * Sam Ruby - * Carlos Valiente - * Till Klampaeckel - * Jim Lindley - * Yoan Blanc - * Michael Gottesman - * Mark Baran - * Michael Hendricks - * Antony Blakey - * Paul Carey - * Hunter Morris - * Brian Palmer - * Maximillian Dornseif - * Eric Casteleijn - * Maarten Thibaut - * Florian Ebeling - * Volker Mische - * Brian Candler - * Brad Anderson - * Nick Gerakines - * Kevin Ilchmann Jørgensen - * Sebastian Cohnen - * Sven Helmberger - * Dan Walters - * Curt Arnold - * Gustavo Niemeyer - * Joshua Bronson - * Kostis Sagonas - * Matthew Hooker - * Ilia Cheishvili - * Lena Herrmann - * Jack Moffit - * Damjan Georgievski - * Jan Kassens - * James Marca - * Matt Goodall - * Joel Clark - * Matt Lyon - * mikeal - * Joscha Feth - * Jarrod Roberson - * Jae Kwon - * Gavin Sherry - * Timothy Smith - * Martin Haaß - * Hans Ulrich Niedermann - * Dmitry Unkovsky - * Zachary Zolton - * Brian Jenkins - * Paul Bonser - * Caleb Land - * Juhani Ränkimies - * Kev Jackson - * Jonathan D. Knezek - * David Rose - * Lim Yue Chuan - * David Davis - * Juuso Väänänen - * Jeff Zellner - * Gabriel Farrell - * Mike Leddy - * Wayne Conrad - * Thomas Vander Stichele - * Felix Hummel - * Tim Smith - * Dipesh Patel - * Sam Bisbee - * Nathan Vander Wilt - * Caolan McMahon - * Andrey Somov - * Chris Coulson - * Trond Norbye - * Christopher Bonhage - * Christian Carter - * Lukasz Mielicki - * Omar Yasin - * Simon Leblanc - * Rogutės Sparnuotos - * Gavin McDonald - * Fedor Indutny - * Tim Blair - * Tady Walsh - * Sam Rijs - * Benjamin Anderson -# Authors from commit 6c976bd and onwards are auto-inserted. If you are merging -# a commit from a non-committer, you should not add an entry to this file. When -# `bootstrap` is run, the actual CONTRIBUTORS file will be generated. diff --git a/INSTALL.Unix.md b/INSTALL.Unix.md deleted file mode 100644 index 6a37f3de4..000000000 --- a/INSTALL.Unix.md +++ /dev/null @@ -1,264 +0,0 @@ -# Apache CouchDB INSTALL.Unix - -A high-level guide to Unix-like systems, inc. Mac OS X and Ubuntu. - -Community installation guides are available on the wiki: - - http://wiki.apache.org/couchdb/Installation - -If you are trying to build CouchDB from a git checkout rather than -a .tar.gz, see the `DEVELOPERS` file. - -This document is the canonical source of installation -information. However, many systems have gotchas that you need to be -aware of. In addition, dependencies frequently change as distributions -update their archives. If you're running into trouble, be sure to -check out the wiki. If you have any tips to share, please also update -the wiki so that others can benefit from your experience. - -## Troubleshooting - -There is a troubleshooting guide: - - http://wiki.apache.org/couchdb/Troubleshooting - -There is a wiki for general documentation: - - http://wiki.apache.org/couchdb/ - -There are collection of friendly mailing lists: - - http://couchdb.apache.org/community/lists.html - -Please work through these in order if you experience any problems. - -## Dependencies - -You should have the following installed: - - * Erlang OTP (>= 19.x) (http://erlang.org/) - * ICU (http://icu-project.org/) - * OpenSSL (http://www.openssl.org/) - * Mozilla SpiderMonkey - either 1.8.5 or 60 - * 60 is not supported on ARM 64-bit (aarch64) at this time. - * https://developer.mozilla.org/en/docs/Mozilla/Projects/SpiderMonkey/Releases/1.8.5 - * https://archive.mozilla.org/pub/firefox/releases/60.9.0esr/source/ (src/js) - * GNU Make (http://www.gnu.org/software/make/) - * GNU Compiler Collection (http://gcc.gnu.org/) - * Python (>=3.5) (http://python.org/) - -To build Fauxton, you should have the following installed: - * Node.JS (>=10.x) (https://nodejs.org/) - -- obtainable from NodeSource (https://github.com/nodesource/distributions) - -To build the documentation, you should have the following installed: - * Python Sphinx (>=1.5) (http://pypi.python.org/pypi/Sphinx) - * Sphinx RT theme (https://github.com/readthedocs/sphinx_rtd_theme) - -It is recommended that you install Erlang OTP 20.3.8.11 or above where -possible. Sphinx and the RTD theme are only required for building the online -documentation. You can disable Fauxton and/or the documentation builds by -adding the --disable-fauxton and/or --disable-docs flag(s) to the configure script. - -### Debian-based Systems - -You can install the dependencies by running: - - sudo apt-get --no-install-recommends -y install \ - build-essential pkg-config erlang erlang-reltool \ - libicu-dev libmozjs-60-dev python3 - -Your distribution may have libmozjs-68-dev instead of 60. Both are supported. - -You can install Node.JS [NodeSource](https://github.com/nodesource/distributions#installation-instructions). - -You can install the documentation dependencies by running: - - sudo apt-get --no-install-recommends -y install \ - python-sphinx - - sudo pip install --upgrade sphinx_rtd_theme nose requests hypothesis - - -Be sure to update the version numbers to match your system's available -packages. - -### RedHat-based (Fedora, Centos, RHEL) Systems - -You can install the dependencies by running: - - sudo yum install autoconf autoconf-archive automake \ - erlang-asn1 erlang-erts erlang-eunit erlang-xmerl \ - libmozjs-60-dev libicu-devel libtool perl-Test-Harness \ - python3 - -You can install Node.JS via [NodeSource](https://github.com/nodesource/distributions#rpminstall). - -The built-in packages for Sphinx in RHEL repositories are too old -to run the documentation build process. Instead, use pip: - - sudo yum install python-pip - sudo pip install --upgrade sphinx nose requests hypothesis - -### Mac OS X - -To build CouchDB from source on Mac OS X, you will need to install -the Command Line Tools: - - xcode-select --install - -You can then install the other dependencies by running: - - brew install autoconf autoconf-archive automake libtool \ - erlang icu4c spidermonkey pkg-config - -You can install Node.JS via the -[official Macintosh installer](https://nodejs.org/en/download/). - -You can install the documentation dependencies by running: - - sudo easy_install pip - sudo pip install --upgrade sphinx nose requests hypothesis - -You will need Homebrew installed to use the brew command. - -Learn more about Homebrew at: - - http://mxcl.github.com/homebrew/ - -Some versions of Mac OS X ship a problematic OpenSSL library. If -you're experiencing troubles with CouchDB crashing intermittently with -a segmentation fault or a bus error, you will need to install your own -version of OpenSSL. See the wiki, mentioned above, for more information. - -### FreeBSD - -FreeBSD requires the use of GNU Make. Where `make` is specified in this -documentation, substitute `gmake`. - -You can install this by running: - - pkg install gmake - -You can install the remaining dependencies by running: - - pkg install openssl icu git bash autoconf \ - www/node npm libtool spidermonkey60 \ - erlang lang/python py37-sphinx py37-pip - pip install --upgrade sphinx_rtd_theme nose requests hypothesis - -## Installing - -Once you have satisfied the dependencies you should run: - - ./configure - -If you wish to customize the installation, pass `--help` to this -script. - -If everything was successful you should see the following message: - - You have configured Apache CouchDB, time to relax. - -Relax. - -To build CouchDB you should run: - - make release - -Try `gmake` if `make` is giving you any problems. - -If everything was successful you should see the following message: - - ... done - You can now copy the rel/couchdb directory anywhere on your system. - Start CouchDB with ./bin/couchdb from within that directory. - -Relax. - -## User Registration - -For OS X, in the steps below, substitute `/Users/couchdb` for `/home/couchdb`. - -You should create a special `couchdb` user for CouchDB. - -On many Unix-like systems you can run: - - adduser --system \ - --home /opt/couchdb \ - --no-create-home \ - --shell /bin/bash \ - --group --gecos \ - "CouchDB Administrator" couchdb - -On Mac OS X you can use the Workgroup Manager to create users up to version -10.9, and dscl or sysadminctl after version 10.9. Search Apple's support -site to find the documentation appropriate for your system. As of recent -versions of OS X, this functionality is also included in Server.app, -available through the App Store only as part of OS X Server. - -You must make sure that the user has a working POSIX shell. - -You can test this by: - - * Trying to log in as the `couchdb` user - - * Running `pwd` and checking the present working directory - -Copy the built couchdb release to the new user's home directory: - - cp -R /path/to/couchdb/rel/couchdb /opt/couchdb - -Change the ownership of the CouchDB directories by running: - - chown -R couchdb:couchdb /opt/couchdb - -Change the permission of the CouchDB directories by running: - - find /opt/couchdb -type d -exec chmod 0770 {} \; - -Update the permissions for your ini files: - - chmod 0644 /opt/couchdb/etc/* - -## First Run - -You can start the CouchDB server by running: - - sudo -i -u couchdb couchdb/bin/couchdb - -This uses the `sudo` command to run the `couchdb` command as the -`couchdb` user. - -When CouchDB starts it should eventually display the following -message: - - Apache CouchDB has started, time to relax. - -Relax. - -To check that everything has worked, point your web browser to: - - http://127.0.0.1:5984/_utils/ - -From here you should verify your installation by pointing your web browser to: - - http://localhost:5984/_utils/#/verifyinstall - -## Running as a daemon - -The couchdb team recommends [runit](http://smarden.org/runit/) to -run CouchDB persistently and reliably. Configuration of runit is -straightforward; if you have questions, reach out to the CouchDB -user mailing list. - -Naturally, you can configure systemd, launchd or SysV-init daemons to -launch CouchDB and keep it running using standard configuration files. -Sample scripts are in the couchdb-pkg repository: - -* SysV-init (Debian-style): https://github.com/apache/couchdb-pkg/blob/master/debian/couchdb.init -* SysV-init (RHEL-style): https://github.com/apache/couchdb-pkg/blob/master/rpm/SOURCES/couchdb.init -* upstart: Use the Debian-style sysvinit script instead. -* systemd: https://github.com/apache/couchdb-pkg/blob/master/debian/couchdb.service - -Consult your system documentation for more information. diff --git a/INSTALL.Windows.md b/INSTALL.Windows.md deleted file mode 100644 index 6cf148c90..000000000 --- a/INSTALL.Windows.md +++ /dev/null @@ -1,21 +0,0 @@ -Apache CouchDB INSTALL.Windows -============================== - -Due to the complexity of building CouchDB on the Windows platform, -full build documentation and all necessary support files are in -the couchdb-glazier repository. - -Be sure to find the branch that matches the release you are building, for -example `couchdb_2.0`. - -Build & Test ------------- -Once all dependencies are built and installed per the documentation in -couchdb-glazier, these commands will configure and build CouchDB: - - powershell -ExecutionPolicy Bypass .\configure.ps1 - make -f Makefile.win check - -This will build couchdb, as well as run the eunit and javascript tests. - -As of CouchDB 2.0 RC1, all tests should pass. diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 048ee41a5..000000000 --- a/LICENSE +++ /dev/null @@ -1,2269 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020 The Apache Foundation - - 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. - -Apache CouchDB Subcomponents - -The Apache CouchDB project includes a number of subcomponents with separate -copyright notices and license terms. Your use of the code for the these -subcomponents is subject to the terms and conditions of the following licenses. - - -For the share/server/json2.js component: - - Public Domain - - No warranty expressed or implied. Use at your own risk. - - -For the share/www/favicon.ico component from https://github.com/BigBlueHat/futon2: - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -For the src/mochiweb component: - - Copyright (c) 2007 Mochi Media, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -For the src/ibrowse component: - - Copyright (c) 2006, Chandrashekhar Mullaparthi - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of the T-Mobile nor the names of its contributors may be - used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -For the src/couch_log/src/couch_log_trunc_io.erl and - the src/couch_log/src/couch_log_trunc_io_fmt.erl components - -ERLANG PUBLIC LICENSE -Version 1.1 - -1. Definitions. - -1.1. ``Contributor'' means each entity that creates or contributes to -the creation of Modifications. - -1.2. ``Contributor Version'' means the combination of the Original -Code, prior Modifications used by a Contributor, and the Modifications -made by that particular Contributor. - -1.3. ``Covered Code'' means the Original Code or Modifications or the -combination of the Original Code and Modifications, in each case -including portions thereof. - -1.4. ``Electronic Distribution Mechanism'' means a mechanism generally -accepted in the software development community for the electronic -transfer of data. - -1.5. ``Executable'' means Covered Code in any form other than Source -Code. - -1.6. ``Initial Developer'' means the individual or entity identified -as the Initial Developer in the Source Code notice required by Exhibit -A. - -1.7. ``Larger Work'' means a work which combines Covered Code or -portions thereof with code not governed by the terms of this License. - -1.8. ``License'' means this document. - -1.9. ``Modifications'' means any addition to or deletion from the -substance or structure of either the Original Code or any previous -Modifications. When Covered Code is released as a series of files, a -Modification is: - -A. Any addition to or deletion from the contents of a file containing - Original Code or previous Modifications. - -B. Any new file that contains any part of the Original Code or - previous Modifications. - -1.10. ``Original Code'' means Source Code of computer software code -which is described in the Source Code notice required by Exhibit A as -Original Code, and which, at the time of its release under this -License is not already Covered Code governed by this License. - -1.11. ``Source Code'' means the preferred form of the Covered Code for -making modifications to it, including all modules it contains, plus -any associated interface definition files, scripts used to control -compilation and installation of an Executable, or a list of source -code differential comparisons against either the Original Code or -another well known, available Covered Code of the Contributor's -choice. The Source Code can be in a compressed or archival form, -provided the appropriate decompression or de-archiving software is -widely available for no charge. - -1.12. ``You'' means an individual or a legal entity exercising rights -under, and complying with all of the terms of, this License. For legal -entities,``You'' includes any entity which controls, is controlled by, -or is under common control with You. For purposes of this definition, -``control'' means (a) the power, direct or indirect, to cause the -direction or management of such entity, whether by contract or -otherwise, or (b) ownership of fifty percent (50%) or more of the -outstanding shares or beneficial ownership of such entity. - -2. Source Code License. - -2.1. The Initial Developer Grant. -The Initial Developer hereby grants You a world-wide, royalty-free, -non-exclusive license, subject to third party intellectual property -claims: - -(a) to use, reproduce, modify, display, perform, sublicense and - distribute the Original Code (or portions thereof) with or without - Modifications, or as part of a Larger Work; and - -(b) under patents now or hereafter owned or controlled by Initial - Developer, to make, have made, use and sell (``Utilize'') the - Original Code (or portions thereof), but solely to the extent that - any such patent is reasonably necessary to enable You to Utilize - the Original Code (or portions thereof) and not to any greater - extent that may be necessary to Utilize further Modifications or - combinations. - -2.2. Contributor Grant. -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license, subject to third party intellectual property -claims: - -(a) to use, reproduce, modify, display, perform, sublicense and - distribute the Modifications created by such Contributor (or - portions thereof) either on an unmodified basis, with other - Modifications, as Covered Code or as part of a Larger Work; and - -(b) under patents now or hereafter owned or controlled by Contributor, - to Utilize the Contributor Version (or portions thereof), but - solely to the extent that any such patent is reasonably necessary - to enable You to Utilize the Contributor Version (or portions - thereof), and not to any greater extent that may be necessary to - Utilize further Modifications or combinations. - -3. Distribution Obligations. - -3.1. Application of License. -The Modifications which You contribute are governed by the terms of -this License, including without limitation Section 2.2. The Source -Code version of Covered Code may be distributed only under the terms -of this License, and You must include a copy of this License with -every copy of the Source Code You distribute. You may not offer or -impose any terms on any Source Code version that alters or restricts -the applicable version of this License or the recipients' rights -hereunder. However, You may include an additional document offering -the additional rights described in Section 3.5. - -3.2. Availability of Source Code. -Any Modification which You contribute must be made available in Source -Code form under the terms of this License either on the same media as -an Executable version or via an accepted Electronic Distribution -Mechanism to anyone to whom you made an Executable version available; -and if made available via Electronic Distribution Mechanism, must -remain available for at least twelve (12) months after the date it -initially became available, or at least six (6) months after a -subsequent version of that particular Modification has been made -available to such recipients. You are responsible for ensuring that -the Source Code version remains available even if the Electronic -Distribution Mechanism is maintained by a third party. - -3.3. Description of Modifications. -You must cause all Covered Code to which you contribute to contain a -file documenting the changes You made to create that Covered Code and -the date of any change. You must include a prominent statement that -the Modification is derived, directly or indirectly, from Original -Code provided by the Initial Developer and including the name of the -Initial Developer in (a) the Source Code, and (b) in any notice in an -Executable version or related documentation in which You describe the -origin or ownership of the Covered Code. - -3.4. Intellectual Property Matters - -(a) Third Party Claims. - If You have knowledge that a party claims an intellectual property - right in particular functionality or code (or its utilization - under this License), you must include a text file with the source - code distribution titled ``LEGAL'' which describes the claim and - the party making the claim in sufficient detail that a recipient - will know whom to contact. If you obtain such knowledge after You - make Your Modification available as described in Section 3.2, You - shall promptly modify the LEGAL file in all copies You make - available thereafter and shall take other steps (such as notifying - appropriate mailing lists or newsgroups) reasonably calculated to - inform those who received the Covered Code that new knowledge has - been obtained. - -(b) Contributor APIs. - If Your Modification is an application programming interface and - You own or control patents which are reasonably necessary to - implement that API, you must also include this information in the - LEGAL file. - -3.5. Required Notices. -You must duplicate the notice in Exhibit A in each file of the Source -Code, and this License in any documentation for the Source Code, where -You describe recipients' rights relating to Covered Code. If You -created one or more Modification(s), You may add your name as a -Contributor to the notice described in Exhibit A. If it is not -possible to put such notice in a particular Source Code file due to -its structure, then you must include such notice in a location (such -as a relevant directory file) where a user would be likely to look for -such a notice. You may choose to offer, and to charge a fee for, -warranty, support, indemnity or liability obligations to one or more -recipients of Covered Code. However, You may do so only on Your own -behalf, and not on behalf of the Initial Developer or any -Contributor. You must make it absolutely clear than any such warranty, -support, indemnity or liability obligation is offered by You alone, -and You hereby agree to indemnify the Initial Developer and every -Contributor for any liability incurred by the Initial Developer or -such Contributor as a result of warranty, support, indemnity or -liability terms You offer. - -3.6. Distribution of Executable Versions. -You may distribute Covered Code in Executable form only if the -requirements of Section 3.1-3.5 have been met for that Covered Code, -and if You include a notice stating that the Source Code version of -the Covered Code is available under the terms of this License, -including a description of how and where You have fulfilled the -obligations of Section 3.2. The notice must be conspicuously included -in any notice in an Executable version, related documentation or -collateral in which You describe recipients' rights relating to the -Covered Code. You may distribute the Executable version of Covered -Code under a license of Your choice, which may contain terms different -from this License, provided that You are in compliance with the terms -of this License and that the license for the Executable version does -not attempt to limit or alter the recipient's rights in the Source -Code version from the rights set forth in this License. If You -distribute the Executable version under a different license You must -make it absolutely clear that any terms which differ from this License -are offered by You alone, not by the Initial Developer or any -Contributor. You hereby agree to indemnify the Initial Developer and -every Contributor for any liability incurred by the Initial Developer -or such Contributor as a result of any such terms You offer. - -3.7. Larger Works. -You may create a Larger Work by combining Covered Code with other code -not governed by the terms of this License and distribute the Larger -Work as a single product. In such a case, You must make sure the -requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Code due to statute -or regulation then You must: (a) comply with the terms of this License -to the maximum extent possible; and (b) describe the limitations and -the code they affect. Such description must be included in the LEGAL -file described in Section 3.4 and must be included with all -distributions of the Source Code. Except to the extent prohibited by -statute or regulation, such description must be sufficiently detailed -for a recipient of ordinary skill to be able to understand it. - -5. Application of this License. - -This License applies to code to which the Initial Developer has -attached the notice in Exhibit A, and to related Covered Code. - -6. CONNECTION TO MOZILLA PUBLIC LICENSE - -This Erlang License is a derivative work of the Mozilla Public -License, Version 1.0. It contains terms which differ from the Mozilla -Public License, Version 1.0. - -7. DISCLAIMER OF WARRANTY. - -COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS, -WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, -WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF -DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR -NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF -THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE -IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER -CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR -CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART -OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER -EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. -This License and the rights granted hereunder will terminate -automatically if You fail to comply with terms herein and fail to cure -such breach within 30 days of becoming aware of the breach. All -sublicenses to the Covered Code which are properly granted shall -survive any termination of this License. Provisions which, by their -nature, must remain in effect beyond the termination of this License -shall survive. - -9. DISCLAIMER OF LIABILITY -Any utilization of Covered Code shall not cause the Initial Developer -or any Contributor to be liable for any damages (neither direct nor -indirect). - -10. MISCELLANEOUS -This License represents the complete agreement concerning the subject -matter hereof. If any provision is held to be unenforceable, such -provision shall be reformed only to the extent necessary to make it -enforceable. This License shall be construed by and in accordance with -the substantive laws of Sweden. Any dispute, controversy or claim -arising out of or relating to this License, or the breach, termination -or invalidity thereof, shall be subject to the exclusive jurisdiction -of Swedish courts, with the Stockholm City Court as the first -instance. - -EXHIBIT A. - -``The contents of this file are subject to the Erlang Public License, -Version 1.1, (the "License"); you may not use this file except in -compliance with the License. You should have received a copy of the -Erlang Public License along with this software. If not, it can be -retrieved via the world wide web at http://www.erlang.org/. - -Software distributed under the License is distributed on an "AS IS" -basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -the License for the specific language governing rights and limitations -under the License. - -The Initial Developer of the Original Code is Ericsson Utvecklings AB. -Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings -AB. All Rights Reserved.'' - - -For the src/ejson/yajl component - -Copyright 2010, Lloyd Hilaiel. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - - 3. Neither the name of Lloyd Hilaiel nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -For the src/ejson/erl_nif_compat.h file - - Copyright (c) 2010-2011 Basho Technologies, Inc. - With some minor modifications for Apache CouchDB. - - This file is provided to you 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. - -For the src/snappy/google-snappy component - - Copyright 2005 and onwards Google Inc. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -For the share/server/coffee-script.js file - - Copyright (c) 2011 Jeremy Ashkenas - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - -for dev/pbkdf2.py - -(The BSD License) - -Copyright (c) 2011 by Armin Ronacher, Reed O'Brien - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -for src/fauxton/assets/js/libs/bootstrap.js -for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -for src/fauxton/assets/js/plugins/prettify.js -for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -for src/fauxton/assets/js/plugins/beautify.js -for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2007-2013 Einar Lielmanis and contributors. - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation files -(the "Software"), to deal in the Software without restriction, -including without limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -for src/fauxton/assets/js/plugins/cloudant.pagingcollection.js -for share/www/js/require* - -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -for src/fauxton/assets/fonts/fontawesome -for share/www/fonts/* - -SIL OPEN FONT LICENSE - -Version 1.1 - 26 February 2007 - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting — in part or in whole — any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. - - -for share/server/60/esprima.js -Based on https://github.com/jquery/esprima - -BSD License - -Copyright JS Foundation and other contributors, https://js.foundation/ - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - -share/server/60/escodegen.js -Based on https://github.com/estools/escodegen - -BSD License - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -for src/fauxton/assets/less/bootstrap/font-awesome/* -for share/www/css/* - -The MIT License (MIT) - -Copyright (c) 2013 Dave Gandy - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -for src/fauxton/test/nightwatch_tests/custom-commands/waitForAttribute.js: - - The MIT License (MIT) - - Copyright (c) 2014 Dave Koo - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - -react-select for share/www/js/require* - - -The MIT License (MIT) - -Copyright (c) 2016 Jed Watson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -jquery for share/www/js/require* - -Copyright jQuery Foundation and other contributors, https://jquery.org/ - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/jquery/jquery - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -All files located in the node_modules and external directories are -externally maintained libraries used by this software which have their -own licenses; we recommend you read them, as their terms may differ from -the terms above. - - -Sizzle for jquery - -Copyright jQuery Foundation and other contributors, https://jquery.org/ - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/jquery/sizzle - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -All files located in the node_modules and external directories are -externally maintained libraries used by this software which have their -own licenses; we recommend you read them, as their terms may differ from -the terms above. - -lodash for share/www/js/require* - -Copyright 2012-2015 The Dojo Foundation -Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -backbone for share/www/js/require* - -Copyright (c) 2010-2016 Jeremy Ashkenas, DocumentCloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - - -d3 for share/www/js/require* - -Copyright (c) 2010-2016, Michael Bostock -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* The name Michael Bostock may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -moment for share/www/js/require* - -Copyright (c) 2011-2016 Tim Wood, Iskren Chernev, Moment.js contributors - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - - -backbone.layoutmanager for share/www/js/require* - -Copyright (c) 2015 Tim Branyen - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -react for share/www/js/require* - -BSD License - -For React software - -Copyright (c) 2013-present, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -for share/www/js/require* as part of react - -BSD License - -For fbjs software - -Copyright (c) 2013-2015, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -object-assign for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -react-dom for share/www/js/require* - -BSD License - -For React software - -Copyright (c) 2013-present, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -flux for share/www/js/require* - -BSD License - -For Flux software - -Copyright (c) 2014-2015, Facebook, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -css-loader for share/www/js/require* - - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra - - -style-loader for for share/www/js/require* - - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra - - -zeroclipboard for share/www/js/require* -zeroclipboard for share/www/js/zeroclipboard - -The MIT License (MIT) -Copyright (c) 2009-2014 Jon Rohan, James M. Greene - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -react-bootstrap for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2014 Stephen J. Collings, Matthew Honnibal, Pieter Vanderwerff - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -babel-runtime for share/www/js/require* (from react-bootstrap) - -Copyright (c) 2014-2016 Sebastian McKenzie - -MIT License - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -core-js for share/www/js/require* (from react-bootstrap) - -Copyright (c) 2015 Denis Pushkarev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -react-prop-types for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2015 react-bootstrap - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -invariant for share/www/js/require* - -BSD-3-Clause -https://opensource.org/licenses/BSD-3-Clause - - -warning for share/www/js/require* - -BSD License - -For React software - -Copyright (c) 2013-2015, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -classnames for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2016 Jed Watson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -dom-helpers for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2015 Jason Quense - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -react-overlays for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2015 react-bootstrap - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -keycode for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2014 Tim Oxley - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -lodash-compat for share/www/js/require* - -Copyright 2012-2016 The Dojo Foundation -Based on Underscore.js, copyright 2009-2016 Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -uncontrollable for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2015 Jason Quense - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -velocity-animate for share/www/js/require* - -The MIT License - -Copyright (c) 2014 Julian Shapiro - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -react-addons-css-transition-group for share/www/js/require* - -BSD License - -For React software - -Copyright (c) 2013-present, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -brace for share/www/js/require* - -Copyright 2013 Thorsten Lorenz. -All rights reserved. - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - - -w3c-blob for share/www/js/require* - -MIT License - - -velocity-react for share/www/js/require* - - -Copyright (c) 2015 Twitter and other contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -react-addons-transition-group for share/www/js/require* - -BSD License - -For React software - -Copyright (c) 2013-present, Facebook, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -react-input-autosize for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2016 Jed Watson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -blacklist for share/www/js/require* - - -visualizeRevTree for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2013 Tomasz Kołodziejski - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -pouchdb for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -process for share/www/js/require* - -(The MIT License) - -Copyright (c) 2013 Roman Shtylman - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -js-extend for share/www/js/require* - -ISC License - - -debug for share/www/js/require* - -(The MIT License) - -Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -ms for share/www/js/require* - -(The MIT License) - -Copyright (c) 2014 Guillermo Rauch - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -inherits for share/www/js/require* - -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - -lie for share/www/js/require* - -#Copyright (c) 2014 Calvin Metcalf - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.** - - -immediate for share/www/js/require* - -Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, Domenic Denicola, Brian Cavalier - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -pouchdb-collections for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -argsarray for share/www/js/require* - -# DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE -## TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. - - -events for share/www/js/require* - -MIT - -Copyright Joyent, Inc. and other Node contributors. - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the -following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. - - -scope-eval for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) 2015 Alex David - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -spark-md for share/www/js/require* - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2015 André Cruz - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. - - -vuvuzela for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -es6-promise-pool for share/www/js/require* - -Copyright (c) 2015 Tim De Pauw - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - - -pouchdb-collate for share/www/js/require* - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - -jsondiffpatch for share/www/js/require* - -The MIT License - -Copyright (c) 2014 Benjamín Eidelman twitter.com/beneidel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - -chalk for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -ansi-styles for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -strip-ansi for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -ansi-regex for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -has-ansi for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -supports-color for share/www/js/require* - -MIT © [Sindre Sorhus](http://sindresorhus.com) - - -escape-string-regexp for share/www/js/require* - -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For the src/hyper component: - -The MIT License (MIT) - -Copyright (c) 2014 Game Analytics ApS - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -For the src/recon component: - -Copyright (c) 2012-2017, Frédéric Trottier-Hébert -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - - The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/Makefile b/Makefile deleted file mode 100644 index 074e47436..000000000 --- a/Makefile +++ /dev/null @@ -1,511 +0,0 @@ -# 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. - -# ******************************************************* -# WARNING! If you edit this file, also edit Makefile.win! -# ******************************************************* - -include version.mk - -REBAR?=$(shell echo `pwd`/bin/rebar) -ERLFMT?=$(shell echo `pwd`/bin/erlfmt) - -# Handle the following scenarios: -# 1. When building from a tarball, use version.mk. -# 2. When building from a clean release tag (#.#.#), use that tag. -# 3. When building from a clean RC tag (#.#.#-RC#), use JUST the version -# number inside the tarball, but use the full name for the name of the -# tarball itself. -# 4. When not on a clean tag, use version.mk + git sha + dirty status. - -COUCHDB_GIT_SHA=$(git_sha) - -IN_RELEASE = $(shell if [ ! -d .git ]; then echo true; fi) -ifeq ($(IN_RELEASE), true) - -# 1. Building from tarball, use version.mk. -COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch) - -else - -# Gather some additional information. -# We do it this way so we don't bake shell-isms into Makefile -# to make it easier to port to Windows. I know, I know. -jst -# IN_RC contains the -RCx suffix in the name if present -IN_RC = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '-RC[0-9]+' 2>/dev/null) -# ON_TAG matches *ONLY* if we are on a release or RC tag -ON_TAG = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+(-RC[0-9]+)?$$' 2>/dev/null) -# REL_TAG contains the #.#.# from git describe, which might be used -REL_TAG = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+' 2>/dev/null) -# DIRTY identifies if we're not on a commit -DIRTY = $(shell git describe --dirty | grep -Eo -- '-dirty' 2>/dev/null) -# COUCHDB_GIT_SHA is our current git hash. -COUCHDB_GIT_SHA=$(shell git rev-parse --short=7 --verify HEAD) - -ifeq ($(ON_TAG),) -# 4. Not on a tag. -COUCHDB_VERSION_SUFFIX = $(COUCHDB_GIT_SHA)$(DIRTY) -COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch)-$(COUCHDB_VERSION_SUFFIX) -else -# 2 and 3. On a tag. -COUCHDB_VERSION = $(REL_TAG)$(DIRTY) -endif -endif - -# needed to do text substitutions -comma:= , -empty:= -space:= $(empty) $(empty) - -DESTDIR= - -# Rebar options -apps= -skip_deps=folsom,meck,mochiweb,triq,proper,snappy,bcrypt,hyper,ibrowse -suites= -tests= - -COMPILE_OPTS=$(shell echo "\ - apps=$(apps) \ - " | sed -e 's/[a-z_]\{1,\}= / /g') -EUNIT_OPTS=$(shell echo "\ - skip_deps=$(skip_deps) \ - suites=$(suites) \ - tests=$(tests) \ - " | sed -e 's/[a-z]\{1,\}= / /g') -DIALYZE_OPTS=$(shell echo "\ - apps=$(apps) \ - skip_deps=$(skip_deps) \ - " | sed -e 's/[a-z]\{1,\}= / /g') -EXUNIT_OPTS=$(subst $(comma),$(space),$(tests)) - -TEST_OPTS="-c 'startup_jitter=0' -c 'default_security=admin_local'" - -################################################################################ -# Main commands -################################################################################ - - -.PHONY: all -# target: all - Build everything -all: couch fauxton docs escriptize - - -.PHONY: help -# target: help - Print this help -help: - @egrep "^# target: " Makefile \ - | sed -e 's/^# target: //g' \ - | sort \ - | awk '{printf(" %-20s", $$1); $$1=$$2=""; print "-" $$0}' - - -################################################################################ -# Building -################################################################################ - - -.PHONY: couch -# target: couch - Build CouchDB core, use ERL_COMPILER_OPTIONS to provide custom compiler's options -couch: config.erl - @COUCHDB_VERSION=$(COUCHDB_VERSION) COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) $(REBAR) compile $(COMPILE_OPTS) - @cp src/couch/priv/couchjs bin/ - - -.PHONY: docs -# target: docs - Build documentation -ifeq ($(IN_RELEASE), true) -docs: share/docs/html -else -docs: src/docs/build -endif - -.PHONY: fauxton -# target: fauxton - Build Fauxton web UI -fauxton: share/www - - -.PHONY: escriptize -# target: escriptize - Build CLI tools -escriptize: couch - @$(REBAR) -r escriptize apps=weatherreport - @cp src/weatherreport/weatherreport bin/weatherreport - - -################################################################################ -# Testing -################################################################################ - - -.PHONY: check -# target: check - Test everything -check: all python-black - @$(MAKE) exunit - @$(MAKE) eunit - @$(MAKE) mango-test - @$(MAKE) elixir-suite - @$(MAKE) weatherreport-test - -ifdef apps -subdirs = $(apps) -else -subdirs=$(shell ls src) -endif - -.PHONY: eunit -# target: eunit - Run EUnit tests, use EUNIT_OPTS to provide custom options -eunit: export BUILDDIR = $(shell pwd) -eunit: export ERL_AFLAGS = -config $(shell pwd)/rel/files/eunit.config -eunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell pwd)/bin/couchjs $(shell pwd)/share/server/main.js -eunit: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -eunit: couch - @COUCHDB_VERSION=$(COUCHDB_VERSION) COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) $(REBAR) setup_eunit 2> /dev/null - @for dir in $(subdirs); do \ - COUCHDB_VERSION=$(COUCHDB_VERSION) COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) $(REBAR) -r eunit $(EUNIT_OPTS) apps=$$dir || exit 1; \ - done - - -.PHONY: exunit -# target: exunit - Run ExUnit tests -exunit: export BUILDDIR = $(shell pwd) -exunit: export MIX_ENV=test -exunit: export ERL_LIBS = $(shell pwd)/src -exunit: export ERL_AFLAGS = -config $(shell pwd)/rel/files/eunit.config -exunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell pwd)/bin/couchjs $(shell pwd)/share/server/main.js -exunit: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -exunit: couch elixir-init setup-eunit elixir-check-formatted elixir-credo - @mix test --trace $(EXUNIT_OPTS) - -setup-eunit: export BUILDDIR = $(shell pwd) -setup-eunit: export ERL_AFLAGS = -config $(shell pwd)/rel/files/eunit.config -setup-eunit: - @$(REBAR) setup_eunit 2> /dev/null - -just-eunit: export BUILDDIR = $(shell pwd) -just-eunit: export ERL_AFLAGS = -config $(shell pwd)/rel/files/eunit.config -just-eunit: - @$(REBAR) -r eunit $(EUNIT_OPTS) - -.PHONY: soak-eunit -soak-eunit: export BUILDDIR = $(shell pwd) -soak-eunit: export ERL_AFLAGS = -config $(shell pwd)/rel/files/eunit.config -soak-eunit: couch - @$(REBAR) setup_eunit 2> /dev/null - while [ $$? -eq 0 ] ; do $(REBAR) -r eunit $(EUNIT_OPTS) ; done - -erlfmt-check: - ERLFMT_PATH=$(ERLFMT) python3 dev/format_check.py - -erlfmt-format: - ERLFMT_PATH=$(ERLFMT) python3 dev/format_all.py - -.venv/bin/black: - @python3 -m venv .venv - @.venv/bin/pip3 install black || touch .venv/bin/black - -# Python code formatter - only runs if we're on Python 3.6 or greater -python-black: .venv/bin/black - @python3 -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \ - echo "Python formatter not supported on Python < 3.6; check results on a newer platform" - @python3 -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \ - LC_ALL=C.UTF-8 LANG=C.UTF-8 .venv/bin/black --check \ - --exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/erlfmt|src/jiffy|src/rebar/pr2relnotes.py|src/fauxton" \ - build-aux/*.py dev/run dev/format_*.py src/mango/test/*.py src/docs/src/conf.py src/docs/ext/*.py . - -python-black-update: .venv/bin/black - @python3 -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \ - echo "Python formatter not supported on Python < 3.6; check results on a newer platform" - @python3 -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \ - LC_ALL=C.UTF-8 LANG=C.UTF-8 .venv/bin/black \ - --exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/rebar/pr2relnotes.py|src/fauxton" \ - build-aux/*.py dev/run src/mango/test/*.py src/docs/src/conf.py src/docs/ext/*.py . - -.PHONY: elixir -elixir: export MIX_ENV=integration -elixir: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -elixir: elixir-init elixir-check-formatted elixir-credo devclean - @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 \ - --enable-erlang-views \ - --locald-config test/elixir/test/config/test-config.ini \ - --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-init -elixir-init: MIX_ENV=test -elixir-init: config.erl - @mix local.rebar --force && mix local.hex --force && mix deps.get - -.PHONY: elixir-cluster-without-quorum -elixir-cluster-without-quorum: export MIX_ENV=integration -elixir-cluster-without-quorum: elixir-init elixir-check-formatted elixir-credo devclean - @dev/run -n 3 -q -a adm:pass \ - --degrade-cluster 2 \ - --no-eval 'mix test --trace --only without_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-cluster-with-quorum -elixir-cluster-with-quorum: export MIX_ENV=integration -elixir-cluster-with-quorum: elixir-init elixir-check-formatted elixir-credo devclean - @dev/run -n 3 -q -a adm:pass \ - --degrade-cluster 1 \ - --no-eval 'mix test --trace --only with_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-suite -elixir-suite: export MIX_ENV=integration -elixir-suite: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -elixir-suite: elixir-init elixir-check-formatted elixir-credo devclean - @dev/run -n 1 -q -a adm:pass \ - --enable-erlang-views \ - --no-join \ - --locald-config test/elixir/test/config/test-config.ini \ - --erlang-config rel/files/eunit.config \ - --no-eval 'mix test --trace --include test/elixir/test/config/suite.elixir --exclude test/elixir/test/config/skip.elixir' - -.PHONY: elixir-check-formatted -elixir-check-formatted: elixir-init - @mix format --check-formatted - -# Credo is a static code analysis tool for Elixir. -# We use it in our tests -.PHONY: elixir-credo -elixir-credo: elixir-init - @mix credo - -.PHONY: build-report -# target: build-report - Generate and upload a build report -build-report: - build-aux/show-test-results.py --suites=10 --tests=10 > test-results.log - build-aux/logfile-uploader.py - -.PHONY: check-qs -# target: check-qs - Run query server tests (ruby and rspec required!) -check-qs: - @QS_LANG=js rspec test/view_server/query_server_spec.rb - - -.PHONY: list-eunit-apps -# target: list-eunit-apps - List EUnit target apps -list-eunit-apps: - @find ./src/ -type f -name *_test.erl -o -name *_tests.erl \ - | cut -d '/' -f 3 \ - | sort -u - - -.PHONY: list-eunit-suites -# target: list-eunit-suites - List EUnit target test suites -list-eunit-suites: - @find ./src/ -type f -name *_test.erl -o -name *_tests.erl -exec basename {} \; \ - | cut -d '.' -f -1 \ - | sort - - -.PHONY: build-test -# target: build-test - Test build script -build-test: - @test/build/test-configure.sh - - -.PHONY: mango-test -# target: mango-test - Run Mango tests -mango-test: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -mango-test: devclean all - @cd src/mango && \ - python3 -m venv .venv && \ - .venv/bin/python3 -m pip install -r requirements.txt - @cd src/mango && ../../dev/run "$(TEST_OPTS)" -n 1 --admin=testuser:testpass '.venv/bin/python3 -m nose2' - - -.PHONY: weatherreport-test -# target: weatherreport-test - Run weatherreport against dev cluster -weatherreport-test: devclean escriptize - @dev/run -n 1 -a adm:pass --no-eval \ - 'bin/weatherreport --etc dev/lib/node1/etc --level error' - -################################################################################ -# Developing -################################################################################ - - -.PHONY: build-plt -# target: build-plt - Build project-specific PLT -build-plt: - @$(REBAR) -r build-plt $(DIALYZE_OPTS) - - -.PHONY: check-plt -# target: check-plt - Check the PLT for consistency and rebuild it if it is not up-to-date -check-plt: - @$(REBAR) -r check-plt $(DIALYZE_OPTS) - - -.PHONY: dialyze -# target: dialyze - Analyze the code for discrepancies -dialyze: .rebar - @$(REBAR) -r dialyze $(DIALYZE_OPTS) - - -.PHONY: introspect -# target: introspect - Check for commits difference between rebar.config and repository -introspect: - @$(REBAR) -r update-deps - @build-aux/introspect - -################################################################################ -# Distributing -################################################################################ - - -.PHONY: dist -# target: dist - Make release tarball -dist: all derived - @./build-aux/couchdb-build-release.sh $(COUCHDB_VERSION) - - @cp -r share/www apache-couchdb-$(COUCHDB_VERSION)/share/ - @mkdir -p apache-couchdb-$(COUCHDB_VERSION)/share/docs/html - @cp -r src/docs/build/html apache-couchdb-$(COUCHDB_VERSION)/share/docs/ - - @mkdir -p apache-couchdb-$(COUCHDB_VERSION)/share/docs/man - @cp src/docs/build/man/apachecouchdb.1 apache-couchdb-$(COUCHDB_VERSION)/share/docs/man/ - - @tar czf apache-couchdb-$(COUCHDB_VERSION)$(IN_RC).tar.gz apache-couchdb-$(COUCHDB_VERSION) - @echo "Done: apache-couchdb-$(COUCHDB_VERSION)$(IN_RC).tar.gz" - - -.PHONY: release -# target: release - Create an Erlang release including CouchDB! --include install.mk -release: all - @echo "Installing CouchDB into rel/couchdb/ ..." - @rm -rf rel/couchdb - @$(REBAR) generate # make full erlang release - @cp bin/weatherreport rel/couchdb/bin/weatherreport - -ifeq ($(with_fauxton), 1) - @mkdir -p rel/couchdb/share/ - @cp -R share/www rel/couchdb/share/ -endif - -ifeq ($(with_docs), 1) -ifeq ($(IN_RELEASE), true) - @mkdir -p rel/couchdb/share/www/docs/ - @mkdir -p rel/couchdb/share/docs/ - @cp -R share/docs/html/* rel/couchdb/share/www/docs/ - @cp share/docs/man/apachecouchdb.1 rel/couchdb/share/docs/couchdb.1 -else - @mkdir -p rel/couchdb/share/www/docs/ - @mkdir -p rel/couchdb/share/docs/ - @cp -R src/docs/build/html/ rel/couchdb/share/www/docs - @cp src/docs/build/man/apachecouchdb.1 rel/couchdb/share/docs/couchdb.1 -endif -endif - - @echo "... done" - @echo - @echo " You can now copy the rel/couchdb directory anywhere on your system." - @echo " Start CouchDB with ./bin/couchdb from within that directory." - @echo - -.PHONY: install -# target: install- install CouchDB :) -install: release - @echo - @echo "Notice: There is no 'make install' command for CouchDB 2.x+." - @echo - @echo " To install CouchDB into your system, copy the rel/couchdb" - @echo " to your desired installation location. For example:" - @echo " cp -r rel/couchdb /usr/local/lib" - @echo - -################################################################################ -# Cleaning -################################################################################ - - -.PHONY: clean -# target: clean - Remove build artifacts -clean: - @$(REBAR) -r clean - @rm -rf .rebar/ - @rm -f bin/couchjs - @rm -f bin/weatherreport - @rm -rf src/*/ebin - @rm -rf src/*/.rebar - @rm -rf src/*/priv/*.so - @rm -rf src/couch/priv/{couchspawnkillable,couchjs} - @rm -rf share/server/main.js share/server/main-coffee.js - @rm -rf tmp dev/data dev/lib dev/logs - @rm -rf src/mango/.venv - @rm -f src/couch/priv/couchspawnkillable - @rm -f src/couch/priv/couch_js/config.h - @rm -f dev/*.beam dev/devnode.* dev/pbkdf2.pyc log/crash.log - @rm -f dev/erlserver.pem dev/couch_ssl_dist.conf - - -.PHONY: distclean -# target: distclean - Remove build and release artifacts -distclean: clean - @rm -f install.mk - @rm -f config.erl - @rm -f rel/couchdb.config -ifneq ($(IN_RELEASE), true) -# when we are in a release, don’t delete the -# copied sources, generated docs, or fauxton - @rm -rf rel/couchdb - @rm -rf share/www - @rm -rf src/docs -endif - - -.PHONY: devclean -# target: devclean - Remove dev cluster artifacts -devclean: - @rm -rf dev/lib/*/data - @rm -rf dev/lib/*/etc - -################################################################################ -# Misc -################################################################################ - - -.rebar: build-plt - -config.erl: - @echo "Apache CouchDB has not been configured." - @echo "Try \"./configure -h\" for help." - @echo - @false - - -src/docs/build: -ifeq ($(with_docs), 1) - @cd src/docs; $(MAKE) -endif - - -share/www: -ifeq ($(with_fauxton), 1) - @echo "Building Fauxton" - @cd src/fauxton && npm install && ./node_modules/grunt-cli/bin/grunt couchdb -endif - - -derived: - @echo "COUCHDB_GIT_SHA: $(COUCHDB_GIT_SHA)" - @echo "COUCHDB_VERSION: $(COUCHDB_VERSION)" - @echo "COUCHDB_VERSION_SUFFIX: $(COUCHDB_VERSION_SUFFIX)" - @echo "DIRTY: $(DIRTY)" - @echo "IN_RC: $(IN_RC)" - @echo "IN_RELEASE: $(IN_RELEASE)" - @echo "ON_TAG: $(ON_TAG)" - @echo "REL_TAG: $(REL_TAG)" - @echo "SUB_VSN: $(SUB_VSN)" diff --git a/Makefile.win b/Makefile.win deleted file mode 100644 index 5bbfeead9..000000000 --- a/Makefile.win +++ /dev/null @@ -1,450 +0,0 @@ -# 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. - -# *************************************************** -# WARNING! If you edit this file, also edit Makefile! -# *************************************************** - -include version.mk - -SHELL=cmd.exe -REBAR?=$(CURDIR)\bin\rebar.cmd -PYTHON=python.exe -ERLFMT?=$(CURDIR)\bin\erlfmt.cmd -MAKE=make -f Makefile.win -# REBAR?=$(shell where rebar.cmd) - -# Handle the following scenarios: -# 1. When building from a tarball, use version.mk. -# 2. When building from a clean release tag (#.#.#), use that tag. -# 3. When building from a clean RC tag (#.#.#-RC#), use JUST the version -# number inside the tarball, but use the full name for the name of the -# tarball itself. -# 4. When not on a clean tag, use version.mk + git sha + dirty status. - -COUCHDB_GIT_SHA=$(git_sha) - -IN_RELEASE = $(shell if not exist .git echo true) - -ifeq ($(IN_RELEASE), true) - -# 1. Building from tarball, use version.mk. -COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch) - -else - -# Gather some additional information. -# We do it this way so we don't bake shell-isms into Makefile -# to make it easier to port to Windows. I know, I know. -jst -# IN_RC contains the -RCx suffix in the name if present -IN_RC = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '-RC[0-9]+' 2>nul) -# ON_TAG matches *ONLY* if we are on a release or RC tag -ON_TAG = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+(-RC[0-9]+)?$$' 2>nul) -# REL_TAG contains the #.#.# from git describe, which might be used -REL_TAG = $(shell git describe --tags --always --first-parent \ - | grep -Eo -- '^[0-9]+\.[0-9]\.[0-9]+' 2>nul) -# DIRTY identifies if we're not on a commit -DIRTY = $(shell git describe --dirty | grep -Eo -- '-dirty' 2>nul) -# COUCHDB_GIT_SHA is our current git hash. -COUCHDB_GIT_SHA=$(shell git rev-parse --short=7 --verify HEAD) - -ifeq ($(ON_TAG),) -# 4. Not on a tag. -COUCHDB_VERSION_SUFFIX = $(COUCHDB_GIT_SHA)$(DIRTY) -COUCHDB_VERSION = $(vsn_major).$(vsn_minor).$(vsn_patch)-$(COUCHDB_VERSION_SUFFIX) -else -# 2 and 3. On a tag. -COUCHDB_VERSION = $(REL_TAG)$(DIRTY) -endif -endif - -# needed to do text substitutions -comma:= , -empty:= -space:= $(empty) $(empty) - -DESTDIR= - -# Rebar options -apps= -skip_deps=folsom,meck,mochiweb,triq,proper,snappy,bcrypt,hyper,ibrowse,local -suites= -tests= - -# no sed on Windows, hard code since apps\suites\tests are empty -EUNIT_OPTS=skip_deps=$(skip_deps) -DIALYZE_OPTS=skip_deps=$(skip_deps) - -EXUNIT_OPTS=$(subst $(comma),$(space),$(tests)) - -TEST_OPTS=-c startup_jitter=0 -c default_security=admin_local - -################################################################################ -# Main commands -################################################################################ - - -.PHONY: all -# target: all - Build everything -all: couch fauxton docs - - -################################################################################ -# Building -################################################################################ - - -.PHONY: couch -# target: couch - Build CouchDB core, use ERL_COMPILER_OPTIONS to provide custom compiler's options -couch: config.erl - @set COUCHDB_VERSION=$(COUCHDB_VERSION) && set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) && $(REBAR) compile $(COMPILE_OPTS) - @copy src\couch\priv\couchjs.exe bin - - -.PHONY: docs -# target: docs - Build documentation -ifeq ($(IN_RELEASE), true) -docs: share\docs\html -else -docs: src\docs\build -endif - -.PHONY: fauxton -# target: fauxton - Build Fauxton web UI -fauxton: share\www - - -################################################################################ -# Testing -################################################################################ - - -.PHONY: check -# target: check - Test everything -check: all python-black - @$(MAKE) eunit - @$(MAKE) mango-test - @$(MAKE) elixir - -ifdef apps -subdirs = $(apps) -else -subdirs=$(shell dir /b src) -endif - -.PHONY: eunit -# target: eunit - Run EUnit tests, use EUNIT_OPTS to provide custom options -eunit: export BUILDDIR = $(shell echo %cd%) -eunit: export ERL_AFLAGS = $(shell echo "-config rel/files/eunit.config") -eunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell echo %cd%)/bin/couchjs $(shell echo %cd%)/share/server/main.js -eunit: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -eunit: couch - @set COUCHDB_VERSION=$(COUCHDB_VERSION) && set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) && $(REBAR) setup_eunit 2> nul - @cmd /c "FOR %d IN ($(subdirs)) DO set COUCHDB_VERSION=$(COUCHDB_VERSION) & set COUCHDB_GIT_SHA=$(COUCHDB_GIT_SHA) & $(REBAR) -r eunit $(EUNIT_OPTS) apps=%d" - -.PHONY: exunit -# target: exunit - Run ExUnit tests -exunit: export BUILDDIR = $(shell echo %cd%) -exunit: export MIX_ENV=test -exunit: export ERL_LIBS = $(shell echo %cd%)\src -exunit: export ERL_AFLAGS = $(shell echo "-config rel/files/eunit.config") -exunit: export COUCHDB_QUERY_SERVER_JAVASCRIPT = $(shell echo %cd%)/bin/couchjs $(shell echo %cd%)/share/server/main.js -exunit: couch elixir-init setup-eunit elixir-check-formatted elixir-credo - @mix test --cover --trace $(EXUNIT_OPTS) - -setup-eunit: export BUILDDIR = $(shell pwd) -setup-eunit: export ERL_AFLAGS = $(shell echo "-config rel/files/eunit.config") -setup-eunit: - @$(REBAR) setup_eunit 2> nul - -just-eunit: export BUILDDIR = $(shell pwd) -just-eunit: export ERL_AFLAGS = $(shell echo "-config rel/files/eunit.config") -just-eunit: - @$(REBAR) -r eunit $(EUNIT_OPTS) - -erlfmt-check: export ERLFMT_PATH := $(ERLFMT) -erlfmt-check: - @$(PYTHON) dev\format_check.py - -erlfmt-format: export ERLFMT_PATH := $(ERLFMT) -erlfmt-format: - @$(PYTHON) dev\format_all.py - -.venv/bin/black: - @$(PYTHON) -m venv .venv - @.venv\Scripts\pip3.exe install black || copy /b .venv\Scripts\black.exe +,, - -# Python code formatter - only runs if we're on Python 3.6 or greater -python-black: .venv/bin/black - @$(PYTHON) -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \ - echo 'Python formatter not supported on Python < 3.6; check results on a newer platform' - @$(PYTHON) -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \ - .venv\Scripts\black.exe --check \ - --exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/erlfmt|src/rebar/pr2relnotes.py|src/fauxton" \ - build-aux dev\run dev\format_*.py src\mango\test src\docs\src\conf.py src\docs\ext . - -python-black-update: .venv/bin/black - @$(PYTHON) -c "import sys; exit(1 if sys.version_info < (3,6) else 0)" || \ - echo 'Python formatter not supported on Python < 3.6; check results on a newer platform' - @$(PYTHON) -c "import sys; exit(1 if sys.version_info >= (3,6) else 0)" || \ - .venv\Scripts\black.exe \ - --exclude="build/|buck-out/|dist/|_build/|\.git/|\.hg/|\.mypy_cache/|\.nox/|\.tox/|\.venv/|src/erlfmt|src/rebar/pr2relnotes.py|src/fauxton" \ - build-aux dev\run dev\format_*.py src\mango\test src\docs\src\conf.py src\docs\ext . - -.PHONY: elixir -elixir: export MIX_ENV=integration -elixir: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -elixir: elixir-init elixir-check-formatted elixir-credo devclean - @dev\run $(TEST_OPTS) -a adm:pass -n 1 --enable-erlang-views \ - --locald-config test/elixir/test/config/test-config.ini \ - --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-init -elixir-init: MIX_ENV=test -elixir-init: config.erl - @mix local.rebar --force && mix local.hex --force && mix deps.get - -.PHONY: elixir-cluster-without-quorum -elixir-cluster-without-quorum: export MIX_ENV=integration -elixir-cluster-without-quorum: elixir-init elixir-check-formatted elixir-credo devclean - @dev\run -n 3 -q -a adm:pass \ - --degrade-cluster 2 \ - --no-eval 'mix test --trace --only without_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-cluster-with-quorum -elixir-cluster-with-quorum: export MIX_ENV=integration -elixir-cluster-with-quorum: elixir-init elixir-check-formatted elixir-credo devclean - @dev\run -n 3 -q -a adm:pass \ - --degrade-cluster 1 \ - --no-eval 'mix test --trace --only with_quorum_test $(EXUNIT_OPTS)' - -.PHONY: elixir-suite -elixir-suite: export MIX_ENV=integration -elixir-suite: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -elixir-suite: elixir-init elixir-check-formatted elixir-credo devclean - @dev\run -n 1 -q -a adm:pass \ - --enable-erlang-views \ - --no-join \ - --locald-config test/elixir/test/config/test-config.ini \ - --erlang-config rel/files/eunit.config \ - --no-eval 'mix test --trace --include test\elixir\test\config\suite.elixir --exclude test\elixir\test\config\skip.elixir' - -.PHONY: elixir-check-formatted -elixir-check-formatted: elixir-init - @mix format --check-formatted - -# Credo is a static code analysis tool for Elixir. -# We use it in our tests -.PHONY: elixir-credo -elixir-credo: elixir-init - @mix credo - -.PHONY: check-qs -# target: check-qs - Run query server tests (ruby and rspec required!) -check-qs: - @QS_LANG=js rspec test\view_server\query_server_spec.rb - - -.PHONY: mango-test -mango-test: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1 -mango-test: devclean all - @cd src\mango && \ - python.exe -m venv .venv && \ - .venv\Scripts\pip.exe install -r requirements.txt - @cd src\mango && .venv\Scripts\python.exe ..\..\dev\run -n 1 --admin=testuser:testpass .venv\Scripts\nose2 - - -################################################################################ -# Developing -################################################################################ - - -.PHONY: build-plt -# target: build-plt - Build project-specific PLT -build-plt: - @$(REBAR) -r build-plt $(DIALYZE_OPTS) - - -.PHONY: check-plt -# target: check-plt - Check the PLT for consistency and rebuild it if it is not up-to-date -check-plt: - @$(REBAR) -r check-plt $(DIALYZE_OPTS) - - -.PHONY: dialyze -# target: dialyze - Analyze the code for discrepancies -dialyze: .rebar - @$(REBAR) -r dialyze $(DIALYZE_OPTS) - - -.PHONY: introspect -# target: introspect - Check for commits difference between rebar.config and repository -introspect: - @$(REBAR) -r update-deps - @escript build-aux\introspect - - -################################################################################ -# Distributing -################################################################################ - - -.PHONY: dist -# target: dist - Make release tarball -dist: all derived - @.\build-aux\couchdb-build-release.sh $(COUCHDB_VERSION) - - @copy -r share\www apache-couchdb-$(COUCHDB_VERSION)\share - @mkdir apache-couchdb-$(COUCHDB_VERSION)\share\docs\html - @copy -r src\docs\build\html apache-couchdb-$(COUCHDB_VERSION)\share\docs - - @mkdir apache-couchdb-$(COUCHDB_VERSION)\share\docs\man - @copy src\docs\build\man\apachecouchdb.1 apache-couchdb-$(COUCHDB_VERSION)\share\docs\man - - @tar czf apache-couchdb-$(COUCHDB_VERSION).tar.gz apache-couchdb-$(COUCHDB_VERSION) - @echo 'Done: apache-couchdb-$(COUCHDB_VERSION).tar.gz' - - -.PHONY: release -# target: release - Create an Erlang release including CouchDB! --include install.mk -release: all - @echo 'Installing CouchDB into rel\couchdb\ ...' - -@rmdir /s/q rel\couchdb - @$(REBAR) generate - @copy src\couch\priv\couchjs.exe rel\couchdb\bin - -ifeq ($(with_fauxton), 1) - -@mkdir rel\couchdb\share - -@xcopy share\www rel\couchdb\share\www /E/I -endif - -ifeq ($(with_docs), 1) - -@mkdir rel\couchdb\share\www\docs - -@mkdir rel\couchdb\share\docs -ifeq ($(IN_RELEASE), true) - @xcopy share\docs\html rel\couchdb\share\www\docs /E /I - @copy share\docs\man\apachecouchdb.1 rel\couchdb\share\docs\couchdb.1 -else - @xcopy src\docs\build\html rel\couchdb\share\www\docs /E /I - @copy src\docs\build\man\apachecouchdb.1 rel\couchdb\share\docs\couchdb.1 -endif -endif - - @echo ... done - @echo . - @echo You can now copy the rel\couchdb directory anywhere on your system. - @echo Start CouchDB with .\bin\couchdb.cmd from within that directory. - @echo . - -.PHONY: install -# target: install- install CouchDB :) -install: release - @echo . - @echo Notice: There is no 'make install' command for CouchDB 2.x+. - @echo . - @echo To install CouchDB into your system, copy the rel\couchdb - @echo to your desired installation location. For example: - @echo xcopy /E rel\couchdb C:\CouchDB\ - @echo . - -################################################################################ -# Cleaning -################################################################################ - - -.PHONY: clean -# target: clean - Remove build artifacts -clean: - @$(REBAR) -r clean - -@rmdir /s/q .rebar - -@del /f/q bin\couchjs.exe - -@rmdir /s/q src\*\ebin - -@rmdir /s/q src\*\.rebar - -@del /f/q/s src\*.dll - -@del /f/q src\couch\priv\*.exe - -@del /f/q share\server\main.js share\server\main-coffee.js - -@rmdir /s/q tmp - -@rmdir /s/q dev\data - -@rmdir /s/q dev\lib - -@rmdir /s/q dev\logs - -@rmdir /s/q src\mango\.venv - -@del /f/q src\couch\priv\couch_js\config.h - -@del /f/q dev\boot_node.beam dev\pbkdf2.pyc log\crash.log - - -.PHONY: distclean -# target: distclean - Remove build and release artifacts -distclean: clean - -@del install.mk - -@del config.erl - -@del rel\couchdb.config -ifneq ($(IN_RELEASE), true) -# when we are in a release, don’t delete the -# copied sources, generated docs, or fauxton - -@rmdir /s/q rel\couchdb - -@rmdir /s/q share\www - -@rmdir /s/q src\docs -endif - - -.PHONY: devclean -# target: devclean - Remove dev cluster artifacts -devclean: - -@rmdir /s/q dev\lib\node1\data - -@rmdir /s/q dev\lib\node2\data - -@rmdir /s/q dev\lib\node3\data - -@rmdir /s/q dev\lib\node1\etc - -@rmdir /s/q dev\lib\node2\etc - -@rmdir /s/q dev\lib\node3\etc - - -################################################################################ -# Misc -################################################################################ - - -.rebar: build-plt - -config.erl: - @echo Apache CouchDB has not been configured. - @echo Try "powershell -ExecutionPolicy Bypass .\configure.ps1 -?" for help. - @echo You probably want "powershell -ExecutionPolicy Bypass .\configure.ps1". - @echo. - @false - - -src\docs\build: - @echo 'Building docs...' -ifeq ($(with_docs), 1) - @cd src\docs && make.bat html && make.bat man -endif - - -share\www: -ifeq ($(with_fauxton), 1) - @echo 'Building Fauxton' - @cd src\fauxton && npm install && .\node_modules\.bin\grunt couchdb -endif - -derived: - @echo "COUCHDB_GIT_SHA: $(COUCHDB_GIT_SHA)" - @echo "COUCHDB_VERSION: $(COUCHDB_VERSION)" - @echo "COUCHDB_VERSION_SUFFIX: $(COUCHDB_VERSION_SUFFIX)" - @echo "DIRTY: $(DIRTY)" - @echo "IN_RC: $(IN_RC)" - @echo "IN_RELEASE: $(IN_RELEASE)" - @echo "ON_TAG: $(ON_TAG)" - @echo "REL_TAG: $(REL_TAG)" - @echo "SUB_VSN: $(SUB_VSN)" diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 8fd1befd2..000000000 --- a/NOTICE +++ /dev/null @@ -1,199 +0,0 @@ -Apache CouchDB -Copyright 2009-2021 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -This product also includes the following third-party components: - -* jQuery (http://jquery.org/) - - Copyright 2012 jQuery Foundation and other contributors - - * json2.js (http://www.json.org/) - - Public domain - - * MochiWeb (http://code.google.com/p/mochiweb/) - - Copyright 2007, Mochi Media Coporation - - * ibrowse (http://github.com/cmullaparthi/ibrowse/tree/master) - - Copyright 2005-2012, Chandrashekhar Mullaparthi - - * mimeparse.js (http://code.google.com/p/mimeparse/) - - Copyright 2009, Chris Anderson - - * base64.js - - Copyright 1999, Masanao Izumo - - * jspec.js (http://visionmedia.github.com/jspec/) - - Copyright 2010 TJ Holowaychuk - - * yajl (http://lloyd.github.com/yajl/) - - Copyright 2010, Lloyd Hilaiel - - * snappy (http://code.google.com/p/snappy/) - - Copyright 2005, Google Inc. - - * snappy-erlang-nif (https://github.com/fdmanana/snappy-erlang-nif) - - Copyright 2011, Filipe David Manana - - * CoffeeScript (http://coffeescript.org/) - - Copyright 2011, Jeremy Ashkenas - - * Sphinx (http://sphinx-doc.org/) - - Copyright 2011, the Sphinx team - - * Sizzle (http://sizzlejs.com/) - - Copyright 2010, The Dojo Foundation - - * Underscore.js 1.4.2 (http://underscorejs.org) - - Copyright 2012, Jeremy Ashkenas - - * backbone.js (http://backbonejs.org/) - - Copyright 2012, Jeremy Ashkenas, DocumentCloud Inc. - - * Bootstrap (http://twitter.github.com/bootstrap/) - - Copyright 2012, Twitter, Inc. - - * d3.js (http://d3js.org) - - Copyright 2012, Michael Bostock - - * Lodash (http://lodash.com/) - - Copyright 2012, John-David Dalton - - * nvd3.js (http://nvd3.org/) - - Copyright 2012, Novus Partners, Inc. - - * backbone.layoutmanager.js (https://github.com/tbranyen/backbone.layoutmanager) - - Copyright 2012, Tim Branyen (@tbranyen) - - * prettify.js (http://code.google.com/p/google-code-prettify/) - - Copyright 2011, Mike Samuel et al - - * PouchDB (https://github.com/daleharvey/pouchdb) - - Copyright 2012, Dale Harvey et al - - * require.js (https://github.com/jrburke/requirejs) - - Copyright (c) 2010-2011, The Dojo Foundation - - * mocha.js (https://github.com/visionmedia/mocha) - - Copyright (c) 2011-2013 TJ Holowaychuk - - * chaijs https://github.com/chaijs - - Copyright (c) 2011-2013 Jake Luer jake@alogicalparadox.com - - * sinon-chai - - Copyright © 2012–2013 Domenic Denicola - - * spin.js - - Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de] - - * font-awesome http://fortawesome.github.io/Font-Awesome/ - - Copyright (c) 2013 Dave Gandy - - * sandbox.js https://github.com/KlausTrainer/sandbox.js - - (c) 2013 Klaus Trainer - - * ace editor https://github.com/ajaxorg/ace - - Copyright (c) 2010, Ajax.org B.V. - - * src/fauxton/asserts/js/plugins/cloudant.pagingcollection.js - - Copyright (c) 2014, Cloudant http://cloudant.com - - * velocity.js (https://github.com/julianshapiro/velocity) - - Copyright (c) 2014 Julian Shapiro - -* is_base_dir function in eunit_plugin.erl (https://github.com/ChicagoBoss/ChicagoBoss/blob/master/skel/priv/rebar/boss_plugin.erl) - - Copyright (c) 2009-2011 Evan Miller - -* ?assertNotMatch in couch_eunit.hrl (https://github.com/richcarl/eunit/blob/master/include/eunit.hrl#L200-L219) - - Copyright (C) 2004-2006 Mickaël Rémond, Richard Carlsson - -* src/fauxton/test/nightwatch_tests/custom-commands/waitForAttribute.js - - Copyright (c) 2014 Dave Koo - -* moment.js - - Copyright (c) 2011-2014 Tim Wood, Iskren Chernev, moment.js contributors - -* React.js - - Copyright (c) 2013-2017, Facebook, Inc. - -* Flux.js - - Copyright (c) 2014, Facebook, Inc. All rights reserved. - -* es5-shim.js - - Copyright (C) 2009-2014 Kristopher Michael Kowal and contributors - -* CSS.escape (https://github.com/mathiasbynens/CSS.escape/) - - Copyright Mathias Bynens - -* Papaparse.js - - Copyright (c) 2015 Matthew Holt - -* react-bootstrap.js - - Copyright (c) 2014 Stephen J. Collings, Matthew Honnibal, Pieter Vanderwerff - -* velocity-react - - Copyright (c) 2015 Twitter, Inc. - -* esprima.js (https://github.com/jquery/esprima) - - Copyright JS Foundation and other contributors, https://js.foundation/ - -* escodegen.js (https://github.com/estools/escodegen) - - Copyright (C) 2012 Yusuke Suzuki (twitter: @Constellation) and other contributors. - -* hyper - - Copyright (c) 2014 Game Analytics ApS - -* recon - - Copyright (c) 2012-2017, Frédéric Trottier-Hébert - -* weatherreport_getopt.erl - - Copyright (C) 2009 Juan Jose Comellas diff --git a/README-DEV.rst b/README-DEV.rst deleted file mode 100644 index 863218de9..000000000 --- a/README-DEV.rst +++ /dev/null @@ -1,256 +0,0 @@ -Apache CouchDB DEVELOPERS -========================= - -Before you start here, read `INSTALL.Unix` (or `INSTALL.Windows`) and -follow the setup instructions including the installation of all the -listed dependencies for your system. - -Only follow these instructions if you are building from a source checkout. - -If you're unsure what this means, ignore this document. - -Dependencies ------------- - -You need the following to run tests: - -* `Python 3 `_ -* `Elixir `_ - -You need the following optionally to build documentation: - -* `Sphinx `_ -* `GNU help2man `_ -* `GnuPG `_ - -You need the following optionally to build releases: - -* `md5sum `_ -* `sha1sum `_ - -You need the following optionally to build Fauxton: - -* `nodejs `_ -* `npm `_ - -You will need these optional dependencies installed if: - -* You are working on the documentation, or -* You are preparing a distribution archive - -However, you do not need them if: - -* You are building from a distribution archive, or -* You don't care about building the documentation - -If you intend to build Fauxton, you will also need to install its -dependencies. After running ``./configure`` to download all of the -dependent repositories, you can read about required dependencies in -`src/fauxton/readme.md`. Typically, installing npm and node.js are -sufficient to enable a Fauxton build. - -Here is a list of *optional* dependencies for various operating systems. -Installation will be easiest, when you install them all. - -Docker -~~~~~~ - -CouchDB maintains a ``Dockerfile`` based on Debian that includes all -the dependencies noted above in the `.devcontainer `_ -folder. - -The ``Dockerfile`` can be used on its own, or together with the -associated ``devcontainer.json`` file to quickly provision a -development environment using `GitHub Codespaces `_ -or `Visual Studio Code `_. - -Debian-based (inc. Ubuntu) Systems -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - sudo apt-get install help2man python-sphinx gnupg nodejs npm \ - python3 python3-venv - -Gentoo-based Systems -~~~~~~~~~~~~~~~~~~~~ - -:: - - sudo emerge gnupg coreutils pkgconfig help2man sphinx python - sudo pip install hypothesis requests nose - -Centos 7 and RHEL 7 -~~~~~~~~~~~~~~~~~~~ - -:: - - sudo yum install help2man python-sphinx python-docutils \ - python-pygments gnupg nodejs npm - - -Mac OS X -~~~~~~~~ - -Install `Homebrew `_, if you do not have -it already. - -Unless you want to install the optional dependencies, skip to the next section. - -Install what else we can with Homebrew:: - - brew install help2man gnupg md5sha1sum node python - -If you don't already have pip installed, install it:: - - sudo easy_install pip - -Now, install the required Python packages:: - - sudo pip install sphinx docutils pygments sphinx_rtd_theme - -FreeBSD -~~~~~~~ - -:: - - pkg install help2man gnupg py27-sphinx node - pip install nose requests hypothesis - -Windows -~~~~~~~ - -Follow the instructions in `INSTALL.Windows` and build all components from -source, using the same Visual C++ compiler and runtime. - -Configuring ------------ - -Configure the source by running:: - - ./configure - -If you intend to run the test suites:: - - ./configure -c - -If you don't want to build Fauxton or documentation specify -``--disable-fauxton`` and/or ``--disable-docs`` arguments for ``configure`` to -ignore their build and avoid any issues with their dependencies. - -See ``./configure --help`` for more information. - -Developing ----------- - -Formatting -~~~~~~~~~~ - -The ``erl`` files in ``src`` are formatted using erlfmt_. The checks are run -for every PR in the CI. To run the checks locally, run ``make erlfmt-check``. -To format the ``erl`` files in ``src``, run ``make erlfmt-format``. -To use ``erlfmt`` for specific files only, use the executable ``bin/erlfmt`` -that is installed by ``configure``. - -.. _erlfmt: https://github.com/WhatsApp/erlfmt - -Testing -------- - -To run all the tests use run:: - - make check - -You can also run each test suite individually via ``eunit`` and ``javascript`` -targets:: - - make eunit - make javascript - -If you need to run specific Erlang tests, you can pass special "options" -to make targets:: - - # Run tests only for couch and chttpd apps - make eunit apps=couch,chttpd - - # Run only tests from couch_btree_tests suite - make eunit apps=couch suites=couch_btree - - # Run only only specific tests - make eunit tests=btree_open_test,reductions_test - - # Ignore tests for specified apps - make eunit skip_deps=couch_log,couch_epi - -The ``apps``, ``suites``, ``tests`` and ``skip_deps`` could be combined in any -way. These are mimics to ``rebar eunit`` arguments. If you're not satisfied by -these, you can use EUNIT_OPT environment variable to specify exact `rebar eunit` -options:: - - make eunit EUNIT_OPTS="apps=couch,chttpd" - -JavaScript tests accepts only `suites` option, but in the same way:: - - # Run all JavaScript tests - make javascript - - # Run only basic and design_options tests - make javascript suites="basic design_options" - - # Ignore specific test suites via command line - make javascript ignore_js_suites="all_docs bulk_docs" - - # Ignore specific test suites in makefile - ignore_js_suites=all_docs,bulk_docs - -Note that tests on the command line are delimited here by whitespace, -not by comma.You can get list of all possible test targets with the -following command:: - - make list-js-suites - -Code analyzer could be run by:: - - make dialyze - -If you need to analyze only specific apps, you can specify them in familiar way -:: - - make dialyze apps=couch,couch_epi - -See ``make help`` for more info and useful commands. - -Please report any problems to the developer's mailing list. - -Releasing ---------- - -The release procedure is documented here:: - - https://cwiki.apache.org/confluence/display/COUCHDB/Release+Procedure - -Unix-like Systems -~~~~~~~~~~~~~~~~~ - -A release tarball can be built by running:: - - make dist - -An Erlang CouchDB release includes the full Erlang Run Time System and -all dependent applications necessary to run CouchDB, standalone. The -release created is completely relocatable on the file system, and is -the recommended way to distribute binaries of CouchDB. A release can be -built by running:: - - make release - -The release can then be found in the rel/couchdb directory. - -Microsoft Windows -~~~~~~~~~~~~~~~~~ - -The release tarball and Erlang CouchDB release commands work on -Microsoft Windows the same as they do on Unix-like systems. To create -a full installer, the separate couchdb-glazier repository is required. -Full instructions are available in that repository's README file. - diff --git a/README.md b/README.md new file mode 100644 index 000000000..91cd09cd5 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +3.x moved to main as of 2022-06-07 + +See https://lists.apache.org/thread/x4lc6vhthj1vkt2xpd0ox5osh959qsc4 diff --git a/README.rst b/README.rst deleted file mode 100644 index 4c51de83b..000000000 --- a/README.rst +++ /dev/null @@ -1,108 +0,0 @@ -Apache CouchDB README -===================== - -+-----+ -| |1| | -+-----+ - -.. |1| image:: https://ci-couchdb.apache.org/job/jenkins-cm1/job/FullPlatformMatrix/job/3.x/badge/icon?subject=3.x - :target: https://ci-couchdb.apache.org/blue/organizations/jenkins/jenkins-cm1%2FFullPlatformMatrix/activity?branch=3.x - -Installation ------------- - -For a high-level guide to Unix-like systems, inc. Mac OS X and Ubuntu, see: - - INSTALL.Unix - -For a high-level guide to Microsoft Windows, see: - - INSTALL.Windows - -Follow the proper instructions to get CouchDB installed on your system. - -If you're having problems, skip to the next section. - -Documentation -------------- - -We have documentation: - - http://docs.couchdb.org/ - -It includes a changelog: - - http://docs.couchdb.org/en/latest/whatsnew/ - -For troubleshooting or cryptic error messages, see: - - http://docs.couchdb.org/en/latest/install/troubleshooting.html - -For general help, see: - - http://couchdb.apache.org/#mailing-list - -We also have an IRC channel: - - http://webchat.freenode.net/?channels=couchdb - -The mailing lists provide a wealth of support and knowledge for you to tap into. -Feel free to drop by with your questions or discussion. See the official CouchDB -website for more information about our community resources. - -Verifying your Installation ---------------------------- - -Run a basic test suite for CouchDB by browsing here: - - http://127.0.0.1:5984/_utils/#verifyinstall - -Getting started with developing -------------------------------- - -For more detail, read the README-DEV.rst file in this directory. - -Basically you just have to install the needed dependencies which are -documented in the install docs and then run ``./configure && make``. - -You don't need to run ``make install`` after compiling, just use -``./dev/run`` to spin up three nodes. You can add haproxy as a caching -layer in front of this cluster by running ``./dev/run --with-haproxy ---haproxy=/path/to/haproxy`` . You will now have a local cluster -listening on port 5984. - -For Fauxton developers fixing the admin-party does not work via the button in -Fauxton. To fix the admin party you have to run ``./dev/run`` with the ``admin`` -flag, e.g. ``./dev/run --admin=username:password``. If you want to have an -admin-party, just omit the flag. - -Contributing to CouchDB ------------------------ - -You can learn more about our contributing process here: - - https://github.com/apache/couchdb/blob/master/CONTRIBUTING.md - -Cryptographic Software Notice ------------------------------ - -This distribution includes cryptographic software. The country in which you -currently reside may have restrictions on the import, possession, use, and/or -re-export to another country, of encryption software. BEFORE using any -encryption software, please check your country's laws, regulations and policies -concerning the import, possession, or use, and re-export of encryption software, -to see if this is permitted. See for more -information. - -The U.S. Government Department of Commerce, Bureau of Industry and Security -(BIS), has classified this software as Export Commodity Control Number (ECCN) -5D002.C.1, which includes information security software using or performing -cryptographic functions with asymmetric algorithms. The form and manner of this -Apache Software Foundation distribution makes it eligible for export under the -License Exception ENC Technology Software Unrestricted (TSU) exception (see the -BIS Export Administration Regulations, Section 740.13) for both object code and -source code. - -The following provides more details on the included cryptographic software: - -CouchDB includes a HTTP client (ibrowse) with SSL functionality. diff --git a/bin/erlang-version.escript b/bin/erlang-version.escript deleted file mode 100644 index 66aae1c41..000000000 --- a/bin/erlang-version.escript +++ /dev/null @@ -1,3 +0,0 @@ - -main(_) -> - io:format("~s~n", [erlang:system_info(otp_release)]). diff --git a/build-aux/Jenkinsfile.full b/build-aux/Jenkinsfile.full deleted file mode 100644 index aeba9e57e..000000000 --- a/build-aux/Jenkinsfile.full +++ /dev/null @@ -1,466 +0,0 @@ -#!groovy -// -// -// 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. - -// Erlang version embedded in binary packages -ERLANG_VERSION = '23' - -// Erlang version used for rebar in release process. CouchDB will not build from -// the release tarball on Erlang versions older than this -MINIMUM_ERLANG_VERSION = '20' - -// We create parallel build / test / package stages for each OS using the metadata -// in this map. Adding a new OS should ideally only involve adding a new entry here. -meta = [ - 'centos7': [ - name: 'CentOS 7', - spidermonkey_vsn: '1.8.5', - image: "apache/couchdbci-centos:7-erlang-${ERLANG_VERSION}" - ], - - 'centos8': [ - name: 'CentOS 8', - spidermonkey_vsn: '60', - image: "apache/couchdbci-centos:8-erlang-${ERLANG_VERSION}" - ], - - 'bionic': [ - name: 'Ubuntu 18.04', - spidermonkey_vsn: '1.8.5', - image: "apache/couchdbci-ubuntu:bionic-erlang-${ERLANG_VERSION}" - ], - - 'focal': [ - name: 'Ubuntu 20.04', - spidermonkey_vsn: '68', - image: "apache/couchdbci-ubuntu:focal-erlang-${ERLANG_VERSION}" - ], - - 'buster': [ - name: 'Debian 10', - spidermonkey_vsn: '60', - image: "apache/couchdbci-debian:buster-erlang-${ERLANG_VERSION}" - ], - - 'bullseye-arm64': [ - name: 'Debian 11 ARM', - spidermonkey_vsn: '78', - image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}", - node_label: 'arm64v8' - ], - - 'bullseye-ppc64': [ - name: 'Debian 11 POWER', - spidermonkey_vsn: '78', - image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}", - node_label: 'ppc64le' - ], - - 'bullseye': [ - name: 'Debian 11', - spidermonkey_vsn: '78', - image: "apache/couchdbci-debian:bullseye-erlang-${ERLANG_VERSION}" - ], - - // Skip freebsd builds for now as adviced by node owner - // 'freebsd': [ - // name: 'FreeBSD', - // spidermonkey_vsn: '1.8.5', - // gnu_make: 'gmake' - // ], - - 'macos': [ - name: 'macOS', - spidermonkey_vsn: '60', - gnu_make: 'make' - ] -] - -// Credit to https://stackoverflow.com/a/69222555 for this technique. -// We can use the scripted pipeline syntax to dynamically generate stages, -// and inject them into a map that we pass to the `parallel` step in a script. -// While the scripting approach is very flexible, it's not able to use some -// functionality specific to Declarative Pipelines, like the `agent` and `post` -// directives, so you'll see alternatives like try-catch-finally used for flow -// control and the nested `node` and `docker` blocks in the container stage to -// configure the worker environment. - -// Returns a build stage suitable for non-containerized environments (currently -// macOS and FreeBSD). Coincidentally we do not currently support automated -// package generation on these platforms. This method in invoked when we create -// `parallelStagesMap` below. -def generateNativeStage(platform) { - return { - stage(platform) { - node(platform) { - timeout(time: 90, unit: "MINUTES") { - try { - // deleteDir is OK here because we're not inside of a Docker container! - deleteDir() - unstash 'tarball' - withEnv([ - 'HOME='+pwd(), - 'PATH+USRLOCAL=/usr/local/bin', - 'MAKE='+meta[platform].gnu_make - ]) { - sh( script: "mkdir -p ${COUCHDB_IO_LOG_DIR} ${platform}/build", label: 'Create build directories' ) - sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/build --strip-components=1", label: 'Unpack release' ) - dir( "${platform}/build" ) { - sh "./configure --skip-deps --spidermonkey-version ${meta[platform].spidermonkey_vsn}" - sh '$MAKE' - sh '$MAKE eunit' - sh '$MAKE elixir-suite' - sh '$MAKE exunit' - sh '$MAKE mango-test' - sh '$MAKE weatherreport-test' - } - } - } - catch (err) { - sh 'ls -l ${WORKSPACE}' - withEnv([ - 'HOME='+pwd(), - 'PATH+USRLOCAL=/usr/local/bin', - 'MAKE='+meta[platform].gnu_make - ]) { - dir( "${platform}/build" ) { - sh 'ls -l' - sh '${MAKE} build-report' - } - } - error("Build step failed with error: ${err.getMessage()}") - } - finally { - junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml' - sh 'killall -9 beam.smp || true' - sh 'rm -rf ${WORKSPACE}/* ${COUCHDB_IO_LOG_DIR}' - } - } - } - } - } -} - -// Returns a build stage suitable for container-based deployments. This method -// is invoked when we create the `parallelStagesMap` in the pipeline below. -def generateContainerStage(platform) { - return { - // Important: the stage name here must match the parallelStagesMap key for the - // Jenkins UI to render the pipeline stages correctly. Don't ask why. -APK - stage(platform) { - node(meta[platform].get('node_label', 'docker')) { - docker.withRegistry('https://docker.io/', 'dockerhub_creds') { - docker.image(meta[platform].image).inside("${DOCKER_ARGS}") { - timeout(time: 90, unit: "MINUTES") { - stage("${meta[platform].name} - build & test") { - try { - sh( script: "rm -rf ${platform} apache-couchdb-*", label: 'Clean workspace' ) - unstash 'tarball' - sh( script: "mkdir -p ${COUCHDB_IO_LOG_DIR} ${platform}/build", label: 'Create build directories' ) - sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/build --strip-components=1", label: 'Unpack release' ) - dir( "${platform}/build" ) { - sh "./configure --skip-deps --spidermonkey-version ${meta[platform].spidermonkey_vsn}" - sh 'make' - sh 'make eunit' - sh 'make elixir-suite' - sh 'make exunit' - sh 'make mango-test' - sh 'make weatherreport-test' - } - } - catch (err) { - sh 'ls -l ${WORKSPACE}' - dir( "${platform}/build" ) { - sh 'ls -l' - sh 'make build-report' - } - error("Build step failed with error: ${err.getMessage()}") - } - finally { - junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml' - sh 'rm -rf ${WORKSPACE}/* ${COUCHDB_IO_LOG_DIR}' - } - } - - stage("${meta[platform].name} - package") { - try { - unstash 'tarball' - sh( script: "mkdir -p ${platform}/couchdb", label: 'Create build directory' ) - sh( script: "tar -xf apache-couchdb-*.tar.gz -C ${platform}/couchdb", label: 'Unpack release' ) - sh( script: "cd ${platform} && git clone https://github.com/apache/couchdb-pkg", label: 'Clone packaging helper repo' ) - dir( "${platform}/couchdb-pkg" ) { - sh( script: 'make', label: 'Build packages' ) - } - sh( label: 'Stage package artifacts for archival', script: """ - rm -rf pkgs/${platform} - mkdir -p pkgs/${platform} - mv ${platform}/rpmbuild/RPMS/\$(arch)/*rpm pkgs/${platform} || true - mv ${platform}/couchdb/*.deb pkgs/${platform} || true - """ ) - archiveArtifacts artifacts: 'pkgs/**', fingerprint: true, onlyIfSuccessful: true - } - catch (err) { - sh 'ls -l ${WORKSPACE}' - error("Build step failed with error: ${err.getMessage()}") - } - finally { - sh 'rm -rf ${WORKSPACE}/*' - } - } - } - } - } - } - } - } -} - -// Finally we have the actual Pipeline. It's mostly a Declarative Pipeline, -// except for the 'Test and Package' stage where we use the `script` step as an -// "escape hatch" to dynamically generate a set of parallel stages to execute. -pipeline { - - // no top-level agent; agents must be declared for each stage - agent none - - environment { - COUCHAUTH = credentials('couchdb_vm2_couchdb') - COUCHDB_IO_LOG_DIR = '/tmp/couchjslogs' - // Following fix an issue with git <= 2.6.5 where no committer - // name or email are present for reflog, required for git clone - GIT_COMMITTER_NAME = 'Jenkins User' - GIT_COMMITTER_EMAIL = 'couchdb@apache.org' - // https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile#64 - // We need the jenkins user mapped inside of the image - // npm config cache below deals with /home/jenkins not mapping correctly - // inside the image - DOCKER_ARGS = '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group' - } - - options { - buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10')) - preserveStashes(buildCount: 10) - timeout(time: 3, unit: 'HOURS') - timestamps() - } - - stages { - stage('Build Release Tarball') { - agent { - docker { - label 'docker' - image "apache/couchdbci-debian:erlang-${MINIMUM_ERLANG_VERSION}" - args "${DOCKER_ARGS}" - registryUrl 'https://docker.io/' - registryCredentialsId 'dockerhub_creds' - } - } - environment { - // TODO find a way to avoid setting this explicitly - spidermonkey = '60' - } - steps { - timeout(time: 15, unit: "MINUTES") { - sh (script: 'rm -rf apache-couchdb-*', label: 'Clean workspace of any previous release artifacts' ) - sh "./configure --spidermonkey-version ${spidermonkey}" - sh 'make erlfmt-check' - sh 'make elixir-check-formatted' - sh 'make dist' - } - } - post { - success { - stash includes: 'apache-couchdb-*.tar.gz', name: 'tarball' - archiveArtifacts artifacts: 'apache-couchdb-*.tar.gz', fingerprint: true - } - failure { - sh 'ls -l ${WORKSPACE}' - } - cleanup { - // UGH see https://issues.jenkins-ci.org/browse/JENKINS-41894 - sh 'rm -rf ${WORKSPACE}/*' - } - } - } // stage Build Release Tarball - - stage('Test and Package') { - steps { - script { - // Including failFast: true in map fails the build immediately if any parallel step fails - parallelStagesMap = meta.collectEntries( [failFast: false] ) { key, values -> - if (values.image) { - ["${key}": generateContainerStage(key)] - } - else { - ["${key}": generateNativeStage(key)] - } - } - parallel parallelStagesMap - } - } - } - - /* - * Example of how to do a qemu-based run, please leave here - */ - -/* - stage('Debian Buster arm64v8') { - // the process is convoluted to ensure we have the latest qemu static binaries on the node first - // before trying to run a foreign docker container type. Alternately ensuring the `update_qemu` - // container is run on every Jenkins agent *after every restart of the Docker daemon* would work. - agent { - any { - } - } - options { - timeout(time: 120, unit: "MINUTES") - } - environment { - platform = 'aarch64-debian-stretch' - sm_ver = '60' - } - stages { - stage('Install latest qemu binaries') { - steps { - sh( script: 'docker run --rm --privileged multiarch/qemu-user-static --reset -p yes' ) - } - } - stage('Pull latest docker image') { - steps { - sh "docker pull apache/couchdbci-debian:arm64v8-buster-erlang-${ERLANG_VERSION}" - } - } - stage('Build from tarball & test & packages') { - steps { - withDockerContainer(image: "apache/couchdbci-debian:arm64v8-buster-erlang-${ERLANG_VERSION}", args: "${DOCKER_ARGS}") { - unstash 'tarball' - withEnv(['MIX_HOME='+pwd(), 'HEX_HOME='+pwd()]) { - sh( script: build_and_test ) - sh( script: make_packages ) - sh( script: cleanup_and_save ) - } - } - } - post { - always { -*/ -// junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml' -/* - } - success { - archiveArtifacts artifacts: 'pkgs/**', fingerprint: true - } - } - } - } // stages - post { - cleanup { - sh 'rm -rf ${WORKSPACE}/*' - } - } // post - } // stage -*/ - - stage('Publish') { - - when { - expression { return env.BRANCH_NAME ==~ /main|2.*.x|3.*.x|4.*.x|jenkins-.*/ } - } - - agent { - docker { - image "apache/couchdbci-debian:erlang-${ERLANG_VERSION}" - label 'docker' - args "${DOCKER_ARGS}" - registryUrl 'https://docker.io/' - registryCredentialsId 'dockerhub_creds' - } - } - options { - skipDefaultCheckout() - timeout(time: 90, unit: "MINUTES") - } - - steps { - withCredentials([sshUserPrivateKey(credentialsId: 'jenkins-key', keyFileVariable: 'KEY')]) { - sh 'rm -rf ${WORKSPACE}/*' - unstash 'tarball' - unarchive mapping: ['pkgs/' : '.'] - - sh( label: 'Retrieve & clean current repo-nightly tree', script: ''' - rsync -avz -e "ssh -o StrictHostKeyChecking=no -i $KEY" jenkins@repo-nightly.couchdb.org:/var/www/html/$BRANCH_NAME . || mkdir -p $BRANCH_NAME - rm -rf $BRANCH_NAME/debian/* $BRANCH_NAME/el6 $BRANCH_NAME/el7/* $BRANCH_NAME/el8/* - mkdir -p $BRANCH_NAME/debian $BRANCH_NAME/el7 $BRANCH_NAME/el8 $BRANCH_NAME/source - rsync -avz -e "ssh -o StrictHostKeyChecking=no -i $KEY" jenkins@repo-nightly.couchdb.org:/var/www/html/js . - ''' ) - - sh( label: 'Build Debian repo', script: ''' - git clone https://github.com/apache/couchdb-pkg - cp js/ubuntu-bionic/*.deb pkgs/bionic - for plat in buster bullseye bionic focal - do - reprepro -b couchdb-pkg/repo includedeb $plat pkgs/$plat/*.deb - done - ''' ) - - sh( label: 'Build CentOS repos', script: ''' - cp js/centos-7/*rpm pkgs/centos7 - cp js/centos-8/*rpm pkgs/centos8 - cd pkgs/centos7 && createrepo_c --database . - cd ../centos8 && createrepo_c --database . - ''' ) - - sh( label: 'Build tree to upload', script: ''' - mv couchdb-pkg/repo/pool $BRANCH_NAME/debian - mv couchdb-pkg/repo/dists $BRANCH_NAME/debian - mv pkgs/centos7/* $BRANCH_NAME/el7 - mv pkgs/centos8/* $BRANCH_NAME/el8 - mv apache-couchdb-*.tar.gz $BRANCH_NAME/source - cd $BRANCH_NAME/source - ls -1tr | head -n -10 | xargs -d '\n' rm -f -- - cd ../.. - ''' ) - - sh( label: 'Sync tree back to repo-nightly', script: ''' - rsync -avz --delete -e "ssh -o StrictHostKeyChecking=no -i $KEY" $BRANCH_NAME jenkins@repo-nightly.couchdb.org:/var/www/html - rm -rf $BRANCH_NAME couchdb-pkg *.tar.gz - ''' ) - } // withCredentials - } // steps - } // stage - } // stages - - post { - success { - mail to: 'notifications@couchdb.apache.org', - replyTo: 'notifications@couchdb.apache.org', - subject: "[Jenkins] SUCCESS: ${currentBuild.fullDisplayName}", - body: "Yay, we passed. ${env.RUN_DISPLAY_URL}" - } - unstable { - mail to: 'notifications@couchdb.apache.org', - replyTo: 'notifications@couchdb.apache.org', - subject: "[Jenkins] SUCCESS: ${currentBuild.fullDisplayName}", - body: "Eep! Build is unstable... ${env.RUN_DISPLAY_URL}" - } - failure { - mail to: 'notifications@couchdb.apache.org', - replyTo: 'notifications@couchdb.apache.org', - subject: "[Jenkins] FAILURE: ${currentBuild.fullDisplayName}", - body: "Boo, we failed. ${env.RUN_DISPLAY_URL}" - } - } - -} // pipeline diff --git a/build-aux/Jenkinsfile.pr b/build-aux/Jenkinsfile.pr deleted file mode 100644 index 2f91961c5..000000000 --- a/build-aux/Jenkinsfile.pr +++ /dev/null @@ -1,203 +0,0 @@ -#!groovy -// -// -// 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. -build_and_test = ''' -mkdir -p ${COUCHDB_IO_LOG_DIR} ${ERLANG_VERSION} -cd ${ERLANG_VERSION} -rm -rf build -mkdir build -cd build -tar -xf ${WORKSPACE}/apache-couchdb-*.tar.gz -cd apache-couchdb-* -./configure -make check || (make build-report && false) -''' - -pipeline { - - // no top-level agent; agents must be declared for each stage - agent none - - environment { - COUCHAUTH = credentials('couchdb_vm2_couchdb') - recipient = 'notifications@couchdb.apache.org' - COUCHDB_IO_LOG_DIR = '/tmp/couchjslogs' - // Following fix an issue with git <= 2.6.5 where no committer - // name or email are present for reflog, required for git clone - GIT_COMMITTER_NAME = 'Jenkins User' - GIT_COMMITTER_EMAIL = 'couchdb@apache.org' - // Parameters for the matrix build - DOCKER_IMAGE_BASE = 'apache/couchdbci-debian:erlang' - // https://github.com/jenkins-infra/jenkins.io/blob/master/Jenkinsfile#64 - // We need the jenkins user mapped inside of the image - // npm config cache below deals with /home/jenkins not mapping correctly - // inside the image - DOCKER_ARGS = '-e npm_config_cache=npm-cache -e HOME=. -v=/etc/passwd:/etc/passwd -v /etc/group:/etc/group' - - // *** BE SURE TO ALSO CHANGE THE ERLANG VERSIONS FARTHER DOWN *** - // Search for ERLANG_VERSION - // see https://issues.jenkins.io/browse/JENKINS-61047 for why this cannot - // be done parametrically - LOW_ERLANG_VER = '20' - - // erlfmt doesn't run with the lowest erlang version so we run it in a - // separate stage with a higher erlang version. - ERLFMT_ERLANG_VER = '23' - } - - options { - buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10')) - // This fails the build immediately if any parallel step fails - parallelsAlwaysFailFast() - preserveStashes(buildCount: 10) - timeout(time: 3, unit: 'HOURS') - timestamps() - } - - stages { - - stage('erlfmt') { - agent { - docker { - image "${DOCKER_IMAGE_BASE}-${ERLFMT_ERLANG_VER}" - label 'docker' - args "${DOCKER_ARGS}" - registryUrl 'https://docker.io/' - registryCredentialsId 'dockerhub_creds' - } - } - options { - timeout(time: 15, unit: "MINUTES") - } - steps { - sh ''' - set - rm -rf apache-couchdb-* - ./configure --skip-deps - make erlfmt-check - ''' - } - post { - cleanup { - // UGH see https://issues.jenkins-ci.org/browse/JENKINS-41894 - sh 'rm -rf ${WORKSPACE}/*' - } - } - } // stage erlfmt - - - stage('Build Release Tarball') { - agent { - docker { - image "${DOCKER_IMAGE_BASE}-${LOW_ERLANG_VER}" - label 'docker' - args "${DOCKER_ARGS}" - registryUrl 'https://docker.io/' - registryCredentialsId 'dockerhub_creds' - } - } - options { - timeout(time: 15, unit: "MINUTES") - } - steps { - sh ''' - set - rm -rf apache-couchdb-* - ./configure - make dist - chmod -R a+w * . - ''' - } - post { - success { - stash includes: 'apache-couchdb-*.tar.gz', name: 'tarball' - } - cleanup { - // UGH see https://issues.jenkins-ci.org/browse/JENKINS-41894 - sh 'rm -rf ${WORKSPACE}/*' - } - } - } // stage Build Release Tarball - - // TODO Rework once Improved Docker Pipeline Engine is released - // https://issues.jenkins-ci.org/browse/JENKINS-47962 - // https://issues.jenkins-ci.org/browse/JENKINS-48050 - - stage('Make Check') { - - matrix { - axes { - axis { - name 'ERLANG_VERSION' - values '20', '21', '22', '23', '24' - } - axis { - name 'SM_VSN' - values '60', '78' - } - } - excludes { - exclude { - axis { - name 'ERLANG_VERSION' - values '20' - } - axis { - name 'SM_VSN' - notValues '60' - } - } - exclude { - axis { - name 'ERLANG_VERSION' - values '21', '22', '23', '24' - } - axis { - name 'SM_VSN' - notValues '78' - } - } - } - - stages { - stage('Build and Test') { - agent { - docker { - image "${DOCKER_IMAGE_BASE}-${ERLANG_VERSION}" - label 'docker' - args "${DOCKER_ARGS}" - } - } - options { - skipDefaultCheckout() - timeout(time: 90, unit: "MINUTES") - } - steps { - unstash 'tarball' - sh( script: build_and_test ) - } - post { - always { - junit '**/.eunit/*.xml, **/_build/*/lib/couchdbtest/*.xml, **/src/mango/nosetests.xml, **/test/javascript/junit.xml' - } - cleanup { - sh 'rm -rf ${WORKSPACE}/* ${COUCHDB_IO_LOG_DIR}' - } - } - } // stage - } // stages - } // matrix - } // stage "Make Check" - } // stages -} // pipeline diff --git a/build-aux/README.md b/build-aux/README.md deleted file mode 100644 index 72cef94b8..000000000 --- a/build-aux/README.md +++ /dev/null @@ -1,131 +0,0 @@ -# CouchDB and Jenkins CI - -In 2019, ASF and CloudBees reached an agreement to allow -the Foundation to use CloudBees Core to have a farm of managed Jenkins -masters. This allows the ASF to give larger projects their own dedicated -Jenkins master, which can be custom configured for the project. They can -readily manage this farm of Jenkins masters centrally, including push -updates to all masters and their plugins. Naturally, this also reduces -contention, as well as providing increased security for project-level -credentials. CouchDB is the first project to use this setup, via -https://ci-couchdb.apache.org/ (aka https://jenkins-cm1.apache.org/) - -Only members of the ASF LDAP group `couchdb-pmc` have write access to -the Jenkins CI server, and all jobs are set to not trust changes to the -Jenkinsfile from forked repos (see below). - -Further, IBM is sponsoring CouchDB with cloud-based worker nodes, for -the project's exclusive use. Combined with the FreeBSD and OSX nodes the -project already had, this will provide the necessary compute resources -to meet the needs of the project for some time to come. - -# Jenkins Configuration - -All jobs on the new Jenkins master are contained in a CouchDB folder. -Credentials for the project are placed within this folder; this is a -unique capability of CloudBees Core at this time. - -## Pull Requests - -[Blue Ocean link](https://ci-couchdb.apache.org/blue/organizations/jenkins/jenkins-cm1%2FPullRequests/activity/) - -To implement build-a-PR functionality in the same way that Travis -performs builds, Jenkins offers the Multibranch Pipeline job. Here's how -it's configured for CouchDB through the GUI: - -* Job name: PullRequests (jobs shouldn't have spaces in them, because - the job name is used for workspace path naming.) -* Display Name: "Pull Requests" -* Description: "This job builds all GitHub pull requests against - apache/couchdb." -* Branch sources: Github - * Credentials: a GitHub API key from wohali. These credentials are - stored in the top-level Jenkins CouchDB folder on the server. - The API token credentials are `user:email` and `repo:status`. - * URL https://github.com/apache/couchdb - * Behaviors - * Discover branches: Exclude branches that are also filed as PRs - * Discover PRs from origin: Merging the PR with the current target - branch revision - * Discover PRs from works: Merging the PR with the current target - branch revision, trust Nobody [2] - * Advanced clone behaviours: - * Fetch tags - * Clear "Shallow clone" [1] - * Clean before checkout [1] - * Prune stale remote-tracking branches - * Property strategy: All branches get the same properties -* Build Configuration - * Mode: by Jenkinsfile - * Script path: `build-aux/Jenkinsfile.pr` -* Scan Repository Triggers - * Periodically if not other wise run - * Interval: 1 day (do not set this too high, GitHub has an API token - throttle that can cause issues!) -* Orphaned Item Strategy - * Discard old items - * Days to keep old items: - * Max # of old items to keep: 10 -* Everything else set as defaults. - -[1]: https://issues.jenkins-ci.org/browse/JENKINS-44598 explains why we have the build set to Clean Before Checkout every time, and why clones are not shallow. - -[2]: https://issues.apache.org/jira/browse/INFRA-17449 explains why "Discover pull requests from forks/Trust" has been set to "Nobody." - -## Full Platform Builds on `main` and release branches - -[![main branch status](https://ci-couchdb.apache.org/job/jenkins-cm1/job/FullPlatformMatrix/job/main/badge/icon?subject=main)](https://ci-couchdb.apache.org/blue/organizations/jenkins/jenkins-cm1%2FFullPlatformMatrix/activity?branch=main) -[![3.x branch status](https://ci-couchdb.apache.org/job/jenkins-cm1/job/FullPlatformMatrix/job/3.x/badge/icon?subject=3.x)](https://ci-couchdb.apache.org/blue/organizations/jenkins/jenkins-cm1%2FFullPlatformMatrix/activity?branch=3.x) - -Our original Jenkins job (formerly `/Jenkinsfile`) is now -`build-aux/Jenkinsfile.full`. This builds CouchDB on `main`, all of -our release branches (`2.*`, `3.*`, etc.) as well as any branch prefixed with -`jenkins-` for testing on a wide variety of supported operating systems. - -Settings are as follows: - -* Job name: FullPlatformMatrix (jobs shouldn't have spaces in them, because - the job name is used for workspace path naming.) -* Display Name: "Full Platform Builds" -* Description: "This job builds on our master and release branches, - and builds packages on all." -* Branch sources: Github - * Credentials: a GitHub API key from wohali. These credentials are - stored in the top-level Jenkins CouchDB folder on the server. - The API token credentials are `user:email` and `repo:status`. - * URL https://github.com/apache/couchdb - * Behaviors - * Discover branches: All branches - * Filter by name (with wildcards): Include: master 2.*.x 3.*.x 4.*.x jenkins-* - * Advanced clone behaviours: - * Fetch tags - * Clear "Shallow clone" [1] - * Clean before checkout [1] - * Prune stale remote-tracking branches - * Property strategy: All branches get the same properties -* Build Configuration - * Mode: by Jenkinsfile - * Script path: `build-aux/Jenkinsfile.pull` -* Scan Repository Triggers - * none -* Orphaned Item Strategy - * Discard old items - * Days to keep old items: - * Max # of old items to keep: 10 -* Everything else set as defaults. - -## Other Resources - -The [apache/couchdb-ci](https://github.com/apache/couchdb-ci) repo contains the -dockerfiles that we use to generate the container images used for our -container-based builds. These images are hosted on Docker Hub in the following -repos: - -* [apache/couchdbci-debian](https://hub.docker.com/r/apache/couchdbci-debian) -* [apache/couchdbci-ubuntu](https://hub.docker.com/r/apache/couchdbci-ubuntu) -* [apache/couchdbci-centos](https://hub.docker.com/r/apache/couchdbci-centos) - -The [apache/couchdb-pkg](https://github.com/apache/couchdb-ci) repo contains -a set of helper scripts to build binary packages for Debian / CentOS / Ubuntu -from the contents of a release tarball. The packaging stage of our "Full -Platform Builds" pipeline clones this repo to produces the package artifacts. diff --git a/build-aux/couchdb-build-release.sh b/build-aux/couchdb-build-release.sh deleted file mode 100755 index dfd529d13..000000000 --- a/build-aux/couchdb-build-release.sh +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/sh -e - -VERSION=$1 - -if [ -z "${VERSION}" ]; then - echo "NO VERSION" - exit 1 -fi - -echo "Building Apache CouchDB ${VERSION}" - -REL_DIR=apache-couchdb-${VERSION} -# make release dir -rm -rf ${REL_DIR} -mkdir ${REL_DIR} - -CURRENT_BRANCH=`git rev-parse --abbrev-ref HEAD` - -# copy sources over -git archive ${CURRENT_BRANCH} | tar -xC ${REL_DIR}/ -f - -cd src/ -for repo in *; do - cd ${repo} - if [ -d ".git" ]; then - mkdir -p ../../${REL_DIR}/src/${repo} - git_ish=`git rev-parse --short HEAD` - git archive ${git_ish} \ - | tar --exclude '*do_not_compile.erl' -xC ../../${REL_DIR}/src/${repo}/ -f - - fi - set +e - grep -rl '{vsn, git}' ../../${REL_DIR}/src/${repo}/ 2>/dev/null \ - | xargs sed -ie "s/{vsn, git}/{vsn, \"${VERSION}\"}/" 2>/dev/null - set -e - cd .. -done - -cd .. - -if test -e .git; then - # save git sha in version.mk - git_sha=`git rev-parse --short HEAD` - echo "git_sha=${git_sha}" >> ${REL_DIR}/version.mk - # create CONTRIBUTORS file - OS=`uname -s` - - sed -e "/^#.*/d" CONTRIBUTORS.in > ${REL_DIR}/CONTRIBUTORS - CONTRIB_EMAIL_SED_COMMAND="s/^[[:blank:]]{5}[[:digit:]]+[[:blank:]]/ * /" - git shortlog -se 6c976bd..HEAD \ - | grep -v @apache.org \ - | sed -E -e "${CONTRIB_EMAIL_SED_COMMAND}" >> ${REL_DIR}/CONTRIBUTORS - echo "" >> ${REL_DIR}/CONTRIBUTORS # simplest portable newline - echo "For a list of authors see the \`AUTHORS\` file." >> ${REL_DIR}/CONTRIBUTORS -fi - -# copy our rebar -cp bin/rebar ${REL_DIR}/bin/rebar diff --git a/build-aux/dist-error b/build-aux/dist-error deleted file mode 100755 index 73486b5db..000000000 --- a/build-aux/dist-error +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -e - -# 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. - -# This script is called by the build system and is used to provide an error -# about missing or empty files. Some files are optional, and will be built when -# the environment allows. But these files are required for distribution. - -cat << EOF -ERROR: This file is missing or incomplete: - - $1 - - This file is optional at build and install time, - but is required when preparing a distribution. -EOF - -exit 1 diff --git a/build-aux/introspect b/build-aux/introspect deleted file mode 100755 index 9b527455f..000000000 --- a/build-aux/introspect +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env escript -%% -*- mode: erlang -*- - -main(_) -> - introspect("rebar.config.script"). - -introspect(File) -> - Bindings = [{'SCRIPT', File}, {'CONFIG', []}], - {ok, Config} = file:script(File, Bindings), - {deps, Deps} = lists:keyfind(deps, 1, Config), - introspect_deps(Deps). - -introspect_deps([]) -> - ok; -introspect_deps([Dep | Rest]) -> - introspect_dep(Dep), - introspect_deps(Rest). - -introspect_dep({App, VsnRegex, {git, Url, From}, _Raw}) -> - introspect_dep({App, VsnRegex, {git, Url, From}}); -introspect_dep({App, _VsnRegex, {git, _Url, From}}) -> - io:format(bold("~s~n"), [App]), - introspect_diff(App, From), - io:format("~n", []), - ok. - -revision({branch, Branch}) -> - Branch; -revision({tag, Tag}) -> - Tag; -revision(Rev) -> - Rev. - -introspect_diff(App, From) -> - introspect_diff(App, revision(From), "origin/master"). - -introspect_diff(App, From, ToBranch) -> - {ok, Log} = sh(App, io_lib:format("git log --pretty=oneline ~s..~s", [From, ToBranch])), - case Log of - [] -> - io:format(" up to date on ~s~n", [bold(ToBranch)]); - _ -> - io:format(" ~B commits behind ~s~n", [length(Log), bold(ToBranch)]), - io:format("~s~n~n", [string:join([" " ++ L || L <- Log], "\n")]) - end. - -sh(App, Cmd) -> - Dir = lists:flatten(["src/", atom_to_list(App)]), - Port = open_port({spawn, lists:flatten(Cmd)}, - [{cd, Dir}, - {line, 16384}, - exit_status, - stderr_to_stdout, - use_stdio]), - read_port(Port). - -read_port(Port) -> - read_port(Port, []). - -read_port(Port, Acc) -> - receive - {Port, {data, {eol, Line}}} -> - read_port(Port, [Line | Acc]); - {Port, {data, {noeol, Line}}} -> - read_port(Port, [Line | Acc]); - {Port, {exit_status, 0}} -> - {ok, lists:reverse(Acc)}; - {Port, {exit_status, Code}} -> - {error, Code, Acc} - end. - -bold(Text) -> - "\e[1m" ++ Text ++ "\e[0m". diff --git a/build-aux/logfile-uploader.py b/build-aux/logfile-uploader.py deleted file mode 100755 index f33915a83..000000000 --- a/build-aux/logfile-uploader.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - - -import datetime -import glob -import json -import os -import tarfile -import time - -import requests - -COUCH_URL = "https://logs.couchdb.org/ci_errorlogs" -TARFILE = "couchlog.tar.gz" - - -def _tojson(req): - """Support requests v0.x as well as 1.x+""" - if requests.__version__[0] == "0": - return json.loads(req.content) - return req.json() - - -def collect_logfiles(): - """Find and tarball all logfiles""" - tb = tarfile.open(name=TARFILE, mode="w:gz") - # Test results - for log in glob.glob("test-results.log"): - tb.add(log) - # EUnit - for log in glob.glob("src/*/.eunit/couch.log"): - tb.add(log) - # JS harness - for log in glob.glob("dev/logs/node1.log"): - tb.add(log) - # couchjs OS process IO logs - for log in glob.glob("/tmp/couchjslogs/*"): - tb.add(log) - tb.close() - - -def build_ci_doc(): - """Build a metadata document with relevant detail from CI env""" - doc = {} - if "TRAVIS" in os.environ: - doc["builder"] = "travis" - doc["build_id"] = os.environ["TRAVIS_JOB_ID"] - doc["erlang"] = os.environ["TRAVIS_OTP_RELEASE"] - doc["url"] = ( - "https://travis-ci.org/apache/couchdb/jobs/" + os.environ["TRAVIS_JOB_ID"] - ) - doc["branch"] = os.environ["TRAVIS_BRANCH"] - doc["commit"] = os.environ["TRAVIS_COMMIT"] - doc["repo"] = "https://github.com/" + os.environ["TRAVIS_REPO_SLUG"] - elif "JENKINS_URL" in os.environ: - doc["builder"] = "jenk-ins" - doc["build_id"] = os.environ["BUILD_NUMBER"] - doc["url"] = os.environ["BUILD_URL"] - doc["branch"] = os.environ["BRANCH_NAME"] - doc["repo"] = "https://github.com/apache/couchdb" - else: - doc["builder"] = "manual" - # TODO: shell out to get correct repo, commit, branch info? - doc["repo"] = "https://github.com/apache/couchdb" - doc["build_id"] = str(time.time()) - - # shorten doc id - repo = doc["repo"].split("/")[-1] - repo = repo.replace(".git", "") - - doc["_id"] = ( - doc["builder"] - + "-" - + repo - + "-" - + doc["build_id"] - + "-" - + datetime.datetime.utcnow().isoformat() - ) - - return doc - - -def upload_logs(): - try: - lp = os.environ["COUCHAUTH"].split(":") - except KeyError as e: - print("ERROR: COUCHAUTH credentials unavailable! " "Unable to upload logfiles.") - exit(1) - - creds = (lp[0], lp[1]) - doc = build_ci_doc() - req = requests.post( - COUCH_URL, - data=json.dumps(doc), - auth=creds, - headers={"Content-type": "application/json"}, - ) - req.raise_for_status() - req = _tojson(req) - with open(TARFILE, "rb") as f: - # ancient versions of requests break if data is iterable - fdata = f.read() - req2 = requests.put( - COUCH_URL + "/" + doc["_id"] + "/" + TARFILE, - headers={"Content-type": "application/x-gtar"}, - auth=creds, - params={"rev": req["rev"]}, - data=fdata, - ) - req2.raise_for_status() - return req2 - - -def main(): - """Find latest logfile and upload to Couch logfile db.""" - print("Uploading logfiles...") - collect_logfiles() - req = upload_logs() - print(req.url.split("?")[0]) - print(req.content) - print("Upload complete!") - - -if __name__ == "__main__": - main() diff --git a/build-aux/print-committerlist.sh b/build-aux/print-committerlist.sh deleted file mode 100755 index f6abc4c78..000000000 --- a/build-aux/print-committerlist.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/sh -# -# 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. - -function get_contributors { - local OS=`uname -s` - case "$OS" in - Linux|CYGWIN*) # GNU sed - local SED_ERE_FLAG=-r - ;; - *) # BSD sed - local SED_ERE_FLAG=-E - ;; - esac - - local CONTRIB_EMAIL_SED_COMMAND="s/^[[:blank:]]{5}[[:digit:]]+[[:blank:]]/ * /" - if [ "$1" == "couchdb-main-repo" ] - then - git shortlog -se 6c976bd..HEAD \ - | grep -v @apache.org \ - | sed $SED_ERE_FLAG -e "$CONTRIB_EMAIL_SED_COMMAND" - else - cd src/$1 - git shortlog -se HEAD \ - | grep -v @apache.org \ - | sed $SED_ERE_FLAG -e "$CONTRIB_EMAIL_SED_COMMAND" - cd .. && cd .. - fi -} - -function print_comitter_list { - # list of external repos that we exclude - local EXCLUDE=("bear" "folsom" "goldrush" "ibrowse" "jiffy" "lager" "meck" "mochiweb" "snappy") - local EXCLUDE=$(printf "\|%s" "${EXCLUDE[@]}") - local EXCLUDE=${EXCLUDE:2} - local SUBREPOS=$(ls src/ | grep -v "$EXCLUDE") - - if test -e .git; then - - { - for i in $SUBREPOS; do - get_contributors $i - done; - get_contributors "couchdb-main-repo" - } | git check-mailmap --stdin | awk ' - BEGIN { - } - { - $1 = ""; - persons[$0] = $0; - } - END { - for (i in persons) { - print persons[i]; - } - }' - fi -} diff --git a/build-aux/show-test-results.py b/build-aux/show-test-results.py deleted file mode 100755 index edd6ca13f..000000000 --- a/build-aux/show-test-results.py +++ /dev/null @@ -1,412 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import glob -import json -import os -import re -import xml.dom.minidom as md - - -TEST_COLLECTIONS = { - "EUnit": "src/**/.eunit/*.xml", - "EXUnit": "_build/integration/lib/couchdbtest/*.xml", - "Mango": "src/mango/*.xml", - "JavaScript": "test/javascript/*.xml", -} - - -def _attrs(elem): - ret = {} - for (k, v) in elem.attributes.items(): - ret[k.lower()] = v - return ret - - -def _text(elem): - rc = [] - for node in elem.childNodes: - if node.nodeType == node.TEXT_NODE: - rc.append(node.data) - else: - rc.append(self._text(node)) - return "".join(rc) - - -class TestCase(object): - def __init__(self, elem): - self.elem = elem - - attrs = _attrs(elem) - - self.name = self._name(attrs) - self.time = float(attrs["time"]) - - self.failure = False - self._check_failure(elem, attrs) - - self.error = False - self._check_error(elem, attrs) - - self.skipped = False - self._check_skipped(elem, attrs) - - def _check_failure(self, elem, attrs): - failures = elem.getElementsByTagName("failure") - if not failures: - return - - self.failure = True - self.failure_msg = _text(failures[0]).strip() - - def _check_error(self, elem, attrs): - errors = elem.getElementsByTagName("error") - if not errors: - return - - self.error = True - self.error_msg = _text(errors[0]).strip() - - def _check_skipped(self, elem, attrs): - skipped = elem.getElementsByTagName("skipped") - if not skipped: - return - - attrs = _attrs(skipped[0]) - self.skipped = True - self.skipped_msg = attrs.get("message", attrs.get("type", "")) - - def _name(self, attrs): - klass = attrs.get("classname", "") - if klass.startswith("Elixir."): - klass = klass[len("Elixir.") :] - if klass: - return "%s - %s" % (klass, attrs["name"]) - return attrs["name"] - - -class TestSuite(object): - SUITE_NAME_PATTERNS = [re.compile("module '([^']+)'"), re.compile("Elixir\.(.+)")] - - def __init__(self, elem): - self.elem = elem - - attrs = _attrs(elem) - - self.name = self._name(attrs) - - self.time = 0.0 - if "time" in attrs: - self.time = float(attrs["time"]) - - self.num_tests = int(attrs["tests"]) - self.num_failures = int(attrs["failures"]) - self.num_errors = int(attrs["errors"]) - self.num_skipped = 0 - - self.tests = [] - self.test_time = 0.0 - - for t_elem in elem.getElementsByTagName("testcase"): - self.tests.append(TestCase(t_elem)) - self.test_time += self.tests[-1].time - if self.tests[-1].skipped: - self.num_skipped += 1 - - if self.time == 0.0 and self.test_time > 0.0: - self.time = self.test_time - - def _name(self, attrs): - raw_name = attrs["name"] - for p in self.SUITE_NAME_PATTERNS: - match = p.match(raw_name) - if match: - return match.group(1) - return raw_name - - -class TestCollection(object): - def __init__(self, name, pattern): - self.name = name - self.pattern = pattern - self.suites = [] - self.bad_files = [] - - for fname in glob.glob(pattern): - self._load_file(fname) - - def _load_file(self, filename): - try: - dom = md.parse(filename) - except: - self.bad_files.append(filename) - return - for elem in dom.getElementsByTagName("testsuite"): - self.suites.append(TestSuite(elem)) - - -def parse_args(): - parser = argparse.ArgumentParser(description="Show test result summaries") - parser.add_argument( - "--ignore-failures", - action="store_true", - default=False, - help="Don't display test failures", - ) - parser.add_argument( - "--ignore-errors", - action="store_true", - default=False, - help="Don't display test errors", - ) - parser.add_argument( - "--ignore-skipped", - action="store_true", - default=False, - help="Don't display skipped tests", - ) - parser.add_argument( - "--all", type=int, default=0, help="Number of rows to show for all groups" - ) - parser.add_argument( - "--collection", - action="append", - default=[], - help="Which collection to display. May be repeated.", - ) - parser.add_argument( - "--suites", type=int, default=0, help="Number of suites to show" - ) - parser.add_argument("--tests", type=int, default=0, help="Number of tests to show") - parser.add_argument( - "--sort", - default="total", - choices=["test", "fixture", "total"], - help="Timing column to sort on", - ) - return parser.parse_args() - - -def display_failures(collections): - failures = [] - for collection in collections: - for suite in collection.suites: - for test in suite.tests: - if not test.failure: - continue - failures.append((test.name, test.failure_msg)) - - if not len(failures): - return - print("Failures") - print("========") - print() - for failure in failures: - print(failure[0]) - print("-" * len(failure[0])) - print() - print(failure[1]) - print() - - -def display_errors(collections): - errors = [] - for collection in collections: - for suite in collection.suites: - for test in suite.tests: - if not test.error: - continue - errors.append((test.name, test.error_msg)) - - if not len(errors): - return - print("Errors") - print("======") - print() - for error in errors: - print(error[0]) - print("-" * len(error[0])) - print() - print(error[1]) - print() - - -def display_skipped(collections): - skipped = [] - for collection in collections: - for suite in collection.suites: - for test in suite.tests: - if not test.skipped: - continue - name = "%s - %s - %s" % (collection.name, suite.name, test.name) - skipped.append((name, test.skipped_msg)) - if not skipped: - return - print("Skipped") - print("=======") - print() - for row in sorted(skipped): - print(" %s: %s" % row) - print() - - -def display_table(table): - for ridx, row in enumerate(table): - new_row = [] - for col in row: - if isinstance(col, float): - new_row.append("%4.1fs" % col) - elif isinstance(col, int): - new_row.append("%d" % col) - else: - new_row.append(col) - table[ridx] = new_row - for row in table: - fmt = " ".join(["%10s"] * len(row)) - print(fmt % tuple(row)) - - -def display_collections(collections, sort): - rows = [] - for collection in collections: - total_time = 0.0 - test_time = 0.0 - num_tests = 0 - num_failures = 0 - num_errors = 0 - num_skipped = 0 - for suite in collection.suites: - total_time += suite.time - test_time += suite.test_time - num_tests += suite.num_tests - num_failures += suite.num_failures - num_errors += suite.num_errors - num_skipped += suite.num_skipped - cols = ( - total_time, - max(0.0, total_time - test_time), - test_time, - num_tests, - num_failures, - num_errors, - num_skipped, - collection.name + " ", - ) - rows.append(cols) - - scol = 0 - if sort == "fixture": - scol = 1 - elif sort == "test": - scol = 2 - - def skey(row): - return (-1.0 * row[scol], row[-1]) - - rows.sort(key=skey) - - print("Collections") - print("===========") - print() - headers = ["Total", "Fixture", "Test", "Count", "Failed", "Errors", "Skipped"] - display_table([headers] + rows) - print() - - -def display_suites(collections, count, sort): - rows = [] - for collection in collections: - for suite in collection.suites: - cols = [ - suite.time, - max(0.0, suite.time - suite.test_time), - suite.test_time, - suite.num_tests, - suite.num_failures, - suite.num_errors, - suite.num_skipped, - collection.name + " - " + suite.name, - ] - rows.append(cols) - - scol = 0 - if sort == "fixture": - scol = 1 - elif sort == "test": - scol = 2 - - def skey(row): - return (-1.0 * row[scol], row[-1]) - - rows.sort(key=skey) - - rows = rows[:count] - - print("Suites") - print("======") - print() - headers = ["Total", "Fixture", "Test", "Count", "Failed", "Errors", "Skipped"] - display_table([headers] + rows) - print() - - -def display_tests(collections, count): - rows = [] - for collection in collections: - for suite in collection.suites: - for test in suite.tests: - if test.failure or test.error or test.skipped: - continue - fmt = "%s - %s - %s" - display = fmt % (collection.name, suite.name, test.name) - rows.append((test.time, display)) - - def skey(row): - return (-1.0 * row[0], row[-1]) - - rows.sort(key=skey) - rows = rows[:count] - - print("Tests") - print("=====") - print() - display_table(rows) - print() - - -def main(): - args = parse_args() - - if not args.collection: - args.collection = ["eunit", "exunit", "mango", "javascript"] - - collections = [] - for (name, pattern) in TEST_COLLECTIONS.items(): - if name.lower() not in args.collection: - continue - collections.append(TestCollection(name, pattern)) - - if not args.ignore_failures: - display_failures(collections) - - if not args.ignore_errors: - display_errors(collections) - - if not args.ignore_skipped: - display_skipped(collections) - - display_collections(collections, args.sort) - - if args.all > 0: - args.suites = args.all - args.tests = args.all - - if args.suites > 0: - display_suites(collections, args.suites, args.sort) - - if args.tests > 0: - display_tests(collections, args.tests) - - -if __name__ == "__main__": - main() diff --git a/build-aux/sphinx-build b/build-aux/sphinx-build deleted file mode 100755 index 8ecf43a55..000000000 --- a/build-aux/sphinx-build +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh -e - -# 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. - -# This script is called by the build system and is used to call sphinx-build if -# is is available, or alternatively, emit a warning, and perform a no-op. Any -# required directories or Makefiles are created and stubbed out as appropriate. - -if test -z "`which sphinx-build`"; then - missing=yes - cat << EOF -WARNING: 'sphinx-build' is needed, and is missing on your system. - You might have modified some files without having the - proper tools for further handling them. -EOF -fi - -if test "$2" = "html"; then - if test "$missing" != "yes"; then - sphinx-build $* - else - mkdir -p html - fi -fi diff --git a/build-aux/sphinx-touch b/build-aux/sphinx-touch deleted file mode 100755 index ed7217de2..000000000 --- a/build-aux/sphinx-touch +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -e - -# 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. - -# This script is called by the build system and is used to touch the list of -# expected output files when sphinx-build is not available. If the files exist, -# this will satisfy make. If they do not exist, we create of empty files. - -if test -z "`which sphinx-build`"; then - for file in $*; do - mkdir -p `dirname $file` - touch $file - done -fi \ No newline at end of file diff --git a/config/config.exs b/config/config.exs deleted file mode 100644 index 8e52433cc..000000000 --- a/config/config.exs +++ /dev/null @@ -1,30 +0,0 @@ -# This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. -use Mix.Config - -# This configuration is loaded before any dependency and is restricted -# to this project. If another project depends on this project, this -# file won't be loaded nor affect the parent project. For this reason, -# if you want to provide default values for your application for -# 3rd-party users, it should be done in your "mix.exs" file. - -# You can configure your application as: -# -# config :couchdbtest, key: :value -# -# and access this configuration in your application as: -# -# Application.get_env(:couchdbtest, :key) -# -# You can also configure a 3rd-party app: -# -# config :logger, level: :info -# - -# It is also possible to import configuration files, relative to this -# directory. For example, you can emulate configuration per environment -# by uncommenting the line below and defining dev.exs, test.exs and such. -# Configuration from the imported file will override the ones defined -# here (which is why it is important to import them last). -# -import_config "#{Mix.env}.exs" \ No newline at end of file diff --git a/config/dev.exs b/config/dev.exs deleted file mode 100644 index d2d855e6d..000000000 --- a/config/dev.exs +++ /dev/null @@ -1 +0,0 @@ -use Mix.Config diff --git a/config/integration.exs b/config/integration.exs deleted file mode 100644 index 796880266..000000000 --- a/config/integration.exs +++ /dev/null @@ -1,9 +0,0 @@ -use Mix.Config - -config :logger, - backends: [:console], - compile_time_purge_level: :debug, - level: :debug - -config :sasl, - sasl_error_logger: false diff --git a/config/prod.exs b/config/prod.exs deleted file mode 100644 index d2d855e6d..000000000 --- a/config/prod.exs +++ /dev/null @@ -1 +0,0 @@ -use Mix.Config diff --git a/config/test.exs b/config/test.exs deleted file mode 100644 index c5a5ed24a..000000000 --- a/config/test.exs +++ /dev/null @@ -1,12 +0,0 @@ -use Mix.Config - -config :logger, - backends: [:console], - compile_time_purge_level: :debug, - level: :debug - -config :kernel, - error_logger: false - -config :sasl, - sasl_error_logger: false diff --git a/configure b/configure deleted file mode 100755 index d8e592b9e..000000000 --- a/configure +++ /dev/null @@ -1,360 +0,0 @@ -#!/bin/sh -e -# 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. - -# next steps: -# try running this, figure out what to do with the vars in the generated files -# in the bottom - -# cd into this script’s directory -rootdir="$(cd "${0%/*}" 2>/dev/null; echo "$PWD")" -basename=`basename $0` - -PACKAGE_AUTHOR_NAME="The Apache Software Foundation" - -REBAR3_BRANCH="main" - -# TEST=0 -WITH_PROPER="true" -WITH_FAUXTON=1 -WITH_DOCS=1 -ERLANG_MD5="false" -SKIP_DEPS=0 - -COUCHDB_USER="$(whoami 2>/dev/null || echo couchdb)" -SM_VSN=${SM_VSN:-"1.8.5"} -ARCH="$(uname -m)" -ERLANG_VER="$(erl -eval 'io:put_chars(erlang:system_info(otp_release)), halt().' -noshell)" - -. ${rootdir}/version.mk -COUCHDB_VERSION=${vsn_major}.${vsn_minor}.${vsn_patch} - -display_help () { - cat << EOF -Usage: $basename [OPTION] - -The $basename command is responsible for generating the build -system for Apache CouchDB. - -Options: - - -h | --help display a short help message and exit - -u | --user USER set the username to run as (defaults to $COUCHDB_USER) - --disable-fauxton do not build Fauxton - --disable-docs do not build any documentation or manpages - --erlang-md5 use erlang for md5 hash operations - --dev alias for --disable-docs --disable-fauxton - --spidermonkey-version VSN specify the version of SpiderMonkey to use (defaults to $SM_VSN) - --skip-deps do not update erlang dependencies - --rebar=PATH use rebar by specified path (version >=2.6.0 && <3.0 required) - --generate-tls-dev-cert generate a cert for TLS distribution (To enable TLS, change the vm.args file.) - --rebar3=PATH use rebar3 by specified path - --erlfmt=PATH use erlfmt by specified path -EOF -} - -# This is just an example to generate a certfile for TLS distribution. -# This is not an endorsement of specific expiration limits, key sizes, or algorithms. -generate_tls_dev_cert() { - if [ ! -e "${rootdir}/dev/erlserver.pem" ]; then - openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem - cat key.pem cert.pem > dev/erlserver.pem && rm key.pem cert.pem - fi - - if [ ! -e "${rootdir}/dev/couch_ssl_dist.conf" ]; then - cat > "${rootdir}/dev/couch_ssl_dist.conf" << EOF -[{server, - [{certfile, "${rootdir}/dev/erlserver.pem"}, - {secure_renegotiate, true}]}, - {client, - [{secure_renegotiate, true}]}]. -EOF - fi -} - -parse_opts() { - while :; do - case $1 in - -h|--help) - display_help - exit - ;; - - --without-proper) - WITH_PROPER="false" - shift - continue - ;; - - --disable-fauxton) - WITH_FAUXTON=0 - shift - continue - ;; - - --disable-docs) - WITH_DOCS=0 - shift - continue - ;; - - --erlang-md5) - ERLANG_MD5="true" - shift - continue - ;; - - --dev) - WITH_DOCS=0 - WITH_FAUXTON=0 - shift - continue - ;; - - --skip-deps) - SKIP_DEPS=1 - shift - continue - ;; - - --rebar) - if [ -x "$2" ]; then - version=`$2 --version 2> /dev/null | grep -o "2\.[6-9]\.[0-9]"` - if [ $? -ne 0 ]; then - printf 'Rebar >=2.6.0 and <3.0.0 required' >&2 - exit 1 - fi - eval REBAR=$2 - shift 2 - continue - else - printf 'ERROR: "--rebar" requires valid path to executable.\n' >&2 - exit 1 - fi - ;; - - --rebar3) - if [ -x "$2" ]; then - eval REBAR3=$2 - shift 2 - continue - else - printf 'ERROR: "--rebar3" requires valid path to executable.\n' >&2 - exit 1 - fi - ;; - - --erlfmt) - if [ -x "$2" ]; then - eval ERLFMT=$2 - shift 2 - continue - else - printf 'ERROR: "--erlfmt" requires valid path to executable.\n' >&2 - exit 1 - fi - ;; - - --user|-u) - if [ -n "$2" ]; then - eval COUCHDB_USER=$2 - shift 2 - continue - else - printf 'ERROR: "--user" requires a non-empty argument.\n' >&2 - exit 1 - fi - ;; - --user=?*) - eval COUCHDB_USER=${1#*=} - ;; - --user=) - printf 'ERROR: "--user" requires a non-empty argument.\n' >&2 - exit 1 - ;; - - --spidermonkey-version) - if [ -n "$2" ]; then - eval SM_VSN=$2 - shift 2 - continue - else - printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2 - exit 1 - fi - ;; - --spidermonkey-version=?*) - eval SM_VSN=${1#*=} - ;; - --spidermonkey-version=) - printf 'ERROR: "--spidermonkey-version" requires a non-empty argument.\n' >&2 - exit 1 - ;; - - --generate-tls-dev-cert) - echo "WARNING: To enable TLS distribution, don't forget to customize vm.args file." - generate_tls_dev_cert - shift - continue - ;; - - --) # End of options - shift - break - ;; - -?*) - echo "WARNING: Unknown option '$1', ignoring" >&2 - shift - ;; - *) # Done - break - esac - shift - done -} - -parse_opts $@ - -if [ "${ARCH}" = "aarch64" ] && [ "${SM_VSN}" = "60" ] -then - echo "ERROR: SpiderMonkey 60 is known broken on ARM 64 (aarch64). Use another version instead." - exit 1 -fi - -echo "==> configuring couchdb in rel/couchdb.config" -cat > rel/couchdb.config << EOF -% 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. -% -% The contents of this file are auto-generated by configure -% -{package_author_name, "$PACKAGE_AUTHOR_NAME"}. -{prefix, "."}. -{data_dir, "./data"}. -{view_index_dir, "./data"}. -{state_dir, "./data"}. -{log_file, "$LOG_FILE"}. -{fauxton_root, "./share/www"}. -{user, "$COUCHDB_USER"}. -{spidermonkey_version, "$SM_VSN"}. -{node_name, "-name couchdb@127.0.0.1"}. -{cluster_port, 5984}. -{backend_port, 5986}. -{prometheus_port, 17986}. -EOF - -cat > install.mk << EOF -# 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. -# -# The contents of this file are auto-generated by configure -# -package_author_name = $PACKAGE_AUTHOR_NAME - -with_fauxton = $WITH_FAUXTON -with_docs = $WITH_DOCS - -user = $COUCHDB_USER -spidermonkey_version = $SM_VSN -EOF - -cat > $rootdir/config.erl << EOF -{with_proper, $WITH_PROPER}. -{erlang_md5, $ERLANG_MD5}. -{spidermonkey_version, "$SM_VSN"}. -EOF - -install_local_rebar() { - if [ ! -x "${rootdir}/bin/rebar" ]; then - if [ ! -d "${rootdir}/src/rebar" ]; then - # git clone --depth 1 https://github.com/apache/couchdb-rebar.git ${rootdir}/src/rebar - git clone https://github.com/apache/couchdb-rebar.git ${rootdir}/src/rebar - fi - make -C ${rootdir}/src/rebar - mv ${rootdir}/src/rebar/rebar ${rootdir}/bin/rebar - make -C ${rootdir}/src/rebar clean - fi -} - -install_local_rebar3() { - if [ ! -x "${rootdir}/bin/rebar3" ]; then - if [ ! -d "${rootdir}/src/rebar3" ]; then - git clone --depth 1 --branch ${REBAR3_BRANCH} https://github.com/erlang/rebar3.git ${rootdir}/src/rebar3 - fi - cd src/rebar3 - ./bootstrap - mv ${rootdir}/src/rebar3/rebar3 ${rootdir}/bin/rebar3 - cd ../.. - fi -} - -install_local_erlfmt() { - if [ ! -x "${rootdir}/bin/erlfmt" ]; then - if [ ! -d "${rootdir}/src/erlfmt" ]; then - git clone --depth 1 https://github.com/WhatsApp/erlfmt.git ${rootdir}/src/erlfmt - fi - cd "${rootdir}"/src/erlfmt - ${REBAR3} as release escriptize - mv ${rootdir}/src/erlfmt/_build/release/bin/erlfmt ${rootdir}/bin/erlfmt - ${REBAR3} clean - cd ../.. - fi -} - -if [ -z "${REBAR}" ]; then - install_local_rebar - REBAR=${rootdir}/bin/rebar -fi - -if [ -z "${REBAR3}" ] && [ "${ERLANG_VER}" != "20" ]; then - install_local_rebar3 - REBAR3=${rootdir}/bin/rebar3 -fi - -if [ -z "${ERLFMT}" ] && [ "${ERLANG_VER}" != "20" ]; then - install_local_erlfmt - ERLFMT=${rootdir}/bin/erlfmt -fi - -# only update dependencies, when we are not in a release tarball -if [ -d .git -a $SKIP_DEPS -ne 1 ]; then - echo "==> updating dependencies" - ${REBAR} get-deps update-deps -fi - -# External repos frequently become integrated with the primary repo, -# resulting in obsolete .git directories, and possible confusion. -# It is usually a good idea to delete these .git directories. -for path in $(find src -name .git -type d); do - git ls-files --error-unmatch $(dirname $path) > /dev/null 2>&1 && \ - echo "WARNING unexpected .git directory $path" -done - -echo "You have configured Apache CouchDB, time to relax. Relax." diff --git a/configure.ps1 b/configure.ps1 deleted file mode 100644 index 54c63776e..000000000 --- a/configure.ps1 +++ /dev/null @@ -1,250 +0,0 @@ -<# -.SYNOPSIS - Configures CouchDB for building. -.DESCRIPTION - This command is responsible for generating the build - system for Apache CouchDB. - - -DisableFauxton request build process skip building Fauxton (default false) - -DisableDocs request build process skip building documentation (default false) - -SkipDeps do not update Erlang dependencies (default false) - -CouchDBUser USER set the username to run as (defaults to current user) - -SpiderMonkeyVersion VSN select the version of SpiderMonkey to use (defaults to 1.8.5) - - Installation directories: - -Prefix PREFIX install architecture-independent files in PREFIX - [C:\Program Files\Apache\CouchDB] - -ExecPrefix EPREFIX install architecture-dependent files in EPREFIX - [same as PREFIX] - - Fine tuning of the installation directories: - -BinDir DIR user executables [EPREFIX\bin] - -LibexecDir DIR program executables [EPREFIX\libexec] - -LibDir DIR object code libraries [EPREFIX\lib] - -SysconfDir DIR read-only single-machine data [PREFIX\etc] - -DataRootDir DIR read-only arch.-independent data root [PREFIX\share] - -LocalStateDir DIR modifiable single-machine data [PREFIX\var] - -RunStateDir DIR modifiable single-machine runstate data [LOCALSTATEDIR\run] - -DatabaseDir DIR specify the data directory [LOCALSTATEDIR\lib] - -ViewindexDir DIR specify the view directory [LOCALSTATEDIR\lib] - -LogDir DIR specify the log directory [LOCALSTATEDIR\log] - -DataDir DIR read-only architecture-independent data [DATAROOTDIR] - -ManDir DIR man documentation [DATAROOTDIR\man] - -DocDir DIR documentation root [DATAROOTDIR\doc\apache-couchdb] - -HTMLDir DIR html documentation [DOCDIR\html] -.LINK - http://couchdb.apache.org/ -#> - -#REQUIRES -Version 2.0 -[cmdletbinding()] - -Param( - [switch]$Test = $false, - [switch]$DisableFauxton = $false, # do not build Fauxton - [switch]$DisableDocs = $false, # do not build any documentation or manpages - [switch]$SkipDeps = $false, # do not update erlang dependencies - - [ValidateNotNullOrEmpty()] - [string]$CouchDBUser = [Environment]::UserName, # set the username to run as (defaults to current user) - [ValidateNotNullOrEmpty()] - [string]$SpiderMonkeyVersion = "1.8.5", # select the version of SpiderMonkey to use (default 1.8.5) - [ValidateNotNullOrEmpty()] - [string]$Prefix = "C:\Program Files\Apache\CouchDB", # install architecture-independent file location (default C:\Program Files\Apache\CouchDB) - [ValidateNotNullOrEmpty()] - [string]$ExecPrefix = $Prefix, # install architecture-dependent file location (default C:\Program Files\Apache\CouchDB) - [ValidateNotNullOrEmpty()] - [string]$BinDir = "$ExecPrefix\bin", # user executable file location (default $ExecPrefix\bin) - [ValidateNotNullOrEmpty()] - [string]$LibExecDir = "$ExecPrefix\libexec", # user executable file location (default $ExecPrefix\libexec) - [ValidateNotNullOrEmpty()] - [string]$LibDir = "$ExecPrefix\lib", # object code libraries (default $ExecPrefix\lib) - [ValidateNotNullOrEmpty()] - - [Alias("EtcDir")] - [string]$SysConfDir = "$Prefix\etc", # read-only single-machine data (default $Prefix\etc) - [ValidateNotNullOrEmpty()] - [string]$DataRootDir = "$Prefix\share", # read-only arch.-independent data root (default $Prefix\share) - - [ValidateNotNullOrEmpty()] - [string]$LocalStateDir = "$Prefix\var", # modifiable single-machine data (default $Prefix\var) - [ValidateNotNullOrEmpty()] - [string]$RunStateDir = "$LocalStateDir\run", # modifiable single-machine run state (default $LocalStateDir\run) - [ValidateNotNullOrEmpty()] - [string]$DatabaseDir = "$LocalStateDir\lib", # database directory (default $LocalStateDir\lib) - [ValidateNotNullOrEmpty()] - [string]$ViewIndexDir = "$LocalStateDir\lib", # database view index directory (default $LocalStateDir\lib) - [ValidateNotNullOrEmpty()] - [string]$LogDir = "$LocalStateDir\log", # logging directory (default $LocalStateDir\log) - - [ValidateNotNullOrEmpty()] - [string]$DataDir = "$DataRootDir", # read-only arch.-independent data (default $DataRootDir) - [ValidateNotNullOrEmpty()] - [string]$ManDir = "$DataRootDir\man", # man documentation (default $DataRootDir\man) - [ValidateNotNullOrEmpty()] - - [string]$DocDir = "$DataRootDir\doc\apache-couchdb", # man documentation (default $DataRootDir\doc\apache-couchdb) - [ValidateNotNullOrEmpty()] - [string]$HTMLDir = "$DocDir\html" # html documentation (default $DocDir\html) -) - - -# determine this script’s directory and change to it -$rootdir = split-path -parent $MyInvocation.MyCommand.Definition -Push-Location $rootdir -[Environment]::CurrentDirectory = $PWD - -# We use this for testing this script -# The test script lives in test/build/test-configure.sh -If ($Test) { - Write-Output @" -"$Prefix" "$ExecPrefix" "$BinDir" "$LibExecDir" "$SysConfDir" "$DataRootDir" "$DataDir" "$LocalStateDir" "$RunStateDir" "$DocDir" "$LibDir" "$DatabaseDir" "$ViewIndexDir" "$LogDir" "$ManDir" "$HTMLDir" -"@ - exit 0 -} - -# Translate ./configure variables to CouchDB variables -$PackageAuthorName="The Apache Software Foundation" -$InstallDir="$LibDir\couchdb" -$LogFile="$LogDir\couch.log" -$BuildFauxton = [int](-not $DisableFauxton) -$BuildDocs = [int](-not $DisableDocs) -$Hostname = [System.Net.Dns]::GetHostEntry([string]"localhost").HostName - -Write-Verbose "==> configuring couchdb in rel\couchdb.config" -$CouchDBConfig = @" -% 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. -% -% The contents of this file are auto-generated by configure -% -{package_author_name, "$PackageAuthorName"}. -{prefix, "."}. -{data_dir, "./data"}. -{view_index_dir, "./data"}. -{log_file, ""}. -{fauxton_root, "./share/www"}. -{user, "$CouchDBUser"}. -{spidermonkey_version, "$SpiderMonkeyVersion"}. -{node_name, "-name couchdb@localhost"}. -{cluster_port, 5984}. -{backend_port, 5986}. -"@ -$CouchDBConfig | Out-File "$rootdir\rel\couchdb.config" -encoding ascii - -#TODO: Output MS NMake file format? Stick with GNU Make? -$InstallMk = @" -# 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. -# -# The contents of this file are auto-generated by configure -# -package_author_name = $PackageAuthorName -install_dir = $InstallDir - -bin_dir = $BinDir -libexec_dir = $LibExecDir\couchdb -doc_dir = $DocDir\couchdb -sysconf_dir = $SysConfDir\couchdb -data_dir = $DataDir\couchdb - -database_dir = $DatabaseDir -view_index_dir = $ViewIndexDir -log_file = $LogFile - -html_dir = $HTMLDir -man_dir = $ManDir - -with_fauxton = $BuildFauxton -with_docs = $BuildDocs - -user = $CouchDBUser -spidermonkey_version = $SpiderMonkeyVersion -"@ -$InstallMk | Out-File "$rootdir\install.mk" -encoding ascii - -$ConfigERL = @" -{spidermonkey_version, "$SpiderMonkeyVersion"}. -"@ -$ConfigERL | Out-File "$rootdir\config.erl" -encoding ascii - -if (((Get-Command "rebar.cmd" -ErrorAction SilentlyContinue) -eq $null) -or - ((Get-Command "rebar3.cmd" -ErrorAction SilentlyContinue) -eq $null) -or - ((Get-Command "erlfmt.cmd" -ErrorAction SilentlyContinue) -eq $null)) { - $env:Path += ";$rootdir\bin" -} - -# check for rebar; if not found, build it and add it to our path -if ((Get-Command "rebar.cmd" -ErrorAction SilentlyContinue) -eq $null) -{ - Write-Verbose "==> rebar.cmd not found; bootstrapping..." - if (-Not (Test-Path "src\rebar")) - { - git clone --depth 1 https://github.com/apache/couchdb-rebar.git $rootdir\src\rebar - } - cmd /c "cd src\rebar && $rootdir\src\rebar\bootstrap.bat" - cp $rootdir\src\rebar\rebar $rootdir\bin\rebar - cp $rootdir\src\rebar\rebar.cmd $rootdir\bin\rebar.cmd - make -C $rootdir\src\rebar clean -} - -# check for rebar3; if not found, build it and add it to our path -if ((Get-Command "rebar3.cmd" -ErrorAction SilentlyContinue) -eq $null) -{ - Write-Verbose "==> rebar3.cmd not found; bootstrapping..." - if (-Not (Test-Path "src\rebar3")) - { - git clone --depth 1 https://github.com/erlang/rebar3.git $rootdir\src\rebar3 - } - cd src\rebar3 - .\bootstrap.ps1 - cp $rootdir\src\rebar3\rebar3 $rootdir\bin\rebar3 - cp $rootdir\src\rebar3\rebar3.cmd $rootdir\bin\rebar3.cmd - cp $rootdir\src\rebar3\rebar3.ps1 $rootdir\bin\rebar3.ps1 - make -C $rootdir\src\rebar3 clean - cd ..\.. -} - -# check for erlfmt; if not found, build it and add it to our path -if ((Get-Command "erlfmt.cmd" -ErrorAction SilentlyContinue) -eq $null) -{ - Write-Verbose "==> erlfmt.cmd not found; bootstrapping..." - if (-Not (Test-Path "src\erlfmt")) - { - git clone --depth 1 https://github.com/WhatsApp/erlfmt.git $rootdir\src\erlfmt - } - cd src\erlfmt - rebar3 as release escriptize - cp $rootdir\src\erlfmt\_build\release\bin\erlfmt $rootdir\bin\erlfmt - cp $rootdir\src\erlfmt\_build\release\bin\erlfmt.cmd $rootdir\bin\erlfmt.cmd - make -C $rootdir\src\erlfmt clean - cd ..\.. -} - -# only update dependencies, when we are not in a release tarball -if ( (Test-Path .git -PathType Container) -and (-not $SkipDeps) ) { - Write-Verbose "==> updating dependencies" - rebar get-deps update-deps -} - -Pop-Location -[Environment]::CurrentDirectory = $PWD -Write-Verbose "You have configured Apache CouchDB, time to relax. Relax." diff --git a/dev/format_all.py b/dev/format_all.py deleted file mode 100644 index 1927fb59e..000000000 --- a/dev/format_all.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - -"""Erlang formatter for CouchDB -Warning: this file needs to run from the CouchDB repo root. -USAGE: ERLFMT_PATH= python3 dev/format_all.py -""" - -import os -import sys -import subprocess - -from format_lib import get_source_paths, get_erlang_version - -if __name__ == "__main__": - if get_erlang_version() < 21: - print("Erlang version is < 21. Skipping format check") - sys.exit(0) - - for path in get_source_paths(): - subprocess.run( - [os.environ["ERLFMT_PATH"], "-w", path], - stdout=subprocess.PIPE, - ) diff --git a/dev/format_check.py b/dev/format_check.py deleted file mode 100644 index cbb0126d9..000000000 --- a/dev/format_check.py +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - -"""Erlang formatter for CouchDB -Warning: this file needs to run from the CouchDB repo root. -USAGE: ERLFMT_PATH= python3 dev/format_check.py -""" - -import os -import subprocess -import sys - -from format_lib import get_source_paths, get_erlang_version - - -if __name__ == "__main__": - if get_erlang_version() < 21: - print("Erlang version is < 21. Skipping format check") - sys.exit(0) - - exit_code = 0 - - for path in get_source_paths(): - run_result = subprocess.run( - [os.environ["ERLFMT_PATH"], "-c", path], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - rc = run_result.returncode - if rc != 0: - print("\n %s error for %s" % (rc, path)) - stderr_lines = run_result.stderr.decode("utf-8").split("\n") - for line in stderr_lines: - print(" > %s" % line, file=sys.stderr) - exit_code = 1 - - sys.exit(exit_code) diff --git a/dev/format_lib.py b/dev/format_lib.py deleted file mode 100644 index 3db0057fc..000000000 --- a/dev/format_lib.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - -"""Erlang formatter lib for CouchDB -Warning: this file is not meant to be executed manually -""" - -import pathlib -import subprocess - - -def get_erlang_version(): - args = [ - "erl", - "-eval", - "io:put_chars(erlang:system_info(otp_release)), halt().", - "-noshell", - ] - res = subprocess.run(args, stdout=subprocess.PIPE, check=True) - str_version = res.stdout.decode("utf-8").strip().strip('"') - return int(str_version) - - -# Generate source paths as "directory/*.erl" wildcard patterns -# those can be directly consumed by erlfmt and processed in parallel -# -def get_source_paths(): - curdir = None - for item in ( - subprocess.run( - ["git", "ls-files", "--", "*.erl"], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - ) - .stdout.decode("utf-8") - .split("\n") - ): - path = pathlib.Path(item) - if path.parent != curdir: - yield str(path.parent.joinpath("*.erl")) - curdir = path.parent - if curdir is not None: - yield str(curdir.joinpath("*.erl")) diff --git a/dev/make_boot_script b/dev/make_boot_script deleted file mode 100755 index 549dd9a07..000000000 --- a/dev/make_boot_script +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env escript - -main(_) -> - {ok, Server} = reltool:start_server([ - {config, "../rel/reltool.config"} - ]), - {ok, Release} = reltool:get_rel(Server, "couchdb"), - ok = file:write_file("devnode.rel", io_lib:format("~p.~n", [Release])), - ok = systools:make_script("devnode", [local]). diff --git a/dev/monitor_parent.erl b/dev/monitor_parent.erl deleted file mode 100644 index 0e9e6c5b7..000000000 --- a/dev/monitor_parent.erl +++ /dev/null @@ -1,41 +0,0 @@ -% 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. - --module(monitor_parent). - --export([start/0]). - -start() -> - {ok, [[PPid]]} = init:get_argument(parent_pid), - spawn(fun() -> monitor_parent(PPid) end). - -monitor_parent(PPid) -> - timer:sleep(1000), - case os:type() of - {unix, _} -> - case os:cmd("kill -0 " ++ PPid) of - "" -> - monitor_parent(PPid); - _Else -> - % Assume _Else is a no such process error - init:stop() - end; - {win32, _} -> - Fmt = "tasklist /fi \"PID eq ~s\" /fo csv /nh", - Retval = os:cmd(io_lib:format(Fmt, [PPid])), - case re:run(Retval, "^\"python.exe\",*") of - {match, _} -> - monitor_parent(PPid); - nomatch -> - init:stop() - end - end. diff --git a/dev/pbkdf2.py b/dev/pbkdf2.py deleted file mode 100644 index 4416f8632..000000000 --- a/dev/pbkdf2.py +++ /dev/null @@ -1,201 +0,0 @@ -# -*- coding: utf-8 -*- -""" - pbkdf2 - ~~~~~~ - - This module implements pbkdf2 for Python. It also has some basic - tests that ensure that it works. The implementation is straightforward - and uses stdlib only stuff and can be easily be copy/pasted into - your favourite application. - - Use this as replacement for bcrypt that does not need a c implementation - of a modified blowfish crypto algo. - - Example usage: - - >>> pbkdf2_hex('what i want to hash', 'the random salt') - 'fa7cc8a2b0a932f8e6ea42f9787e9d36e592e0c222ada6a9' - - How to use this: - - 1. Use a constant time string compare function to compare the stored hash - with the one you're generating:: - - def safe_str_cmp(a, b): - if len(a) != len(b): - return False - rv = 0 - for x, y in izip(a, b): - rv |= ord(x) ^ ord(y) - return rv == 0 - - 2. Use `os.urandom` to generate a proper salt of at least 8 byte. - Use a unique salt per hashed password. - - 3. Store ``algorithm$salt:costfactor$hash`` in the database so that - you can upgrade later easily to a different algorithm if you need - one. For instance ``PBKDF2-256$thesalt:10000$deadbeef...``. - - - :copyright: (c) Copyright 2011 by Armin Ronacher. - :license: BSD, see LICENSE for more details. -""" -from binascii import hexlify -import hmac -import hashlib -import sys -from struct import Struct -from operator import xor -from itertools import starmap - -PY3 = sys.version_info[0] == 3 - -if not PY3: - from itertools import izip as zip - -if PY3: - text_type = str -else: - text_type = unicode - - -_pack_int = Struct(">I").pack - - -def bytes_(s, encoding="utf8", errors="strict"): - if isinstance(s, text_type): - return s.encode(encoding, errors) - return s - - -def hexlify_(s): - if PY3: - return str(hexlify(s), encoding="utf8") - else: - return s.encode("hex") - - -def range_(*args): - if PY3: - return range(*args) - else: - return xrange(*args) - - -def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None): - """Like :func:`pbkdf2_bin` but returns a hex encoded string.""" - return hexlify_(pbkdf2_bin(data, salt, iterations, keylen, hashfunc)) - - -def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None): - """Returns a binary digest for the PBKDF2 hash algorithm of `data` - with the given `salt`. It iterates `iterations` time and produces a - key of `keylen` bytes. By default SHA-1 is used as hash function, - a different hashlib `hashfunc` can be provided. - """ - hashfunc = hashfunc or hashlib.sha1 - mac = hmac.new(bytes_(data), None, hashfunc) - - def _pseudorandom(x, mac=mac): - h = mac.copy() - h.update(bytes_(x)) - if PY3: - return [x for x in h.digest()] - else: - return map(ord, h.digest()) - - buf = [] - for block in range_(1, -(-keylen // mac.digest_size) + 1): - rv = u = _pseudorandom(bytes_(salt) + _pack_int(block)) - for i in range_(iterations - 1): - if PY3: - u = _pseudorandom(bytes(u)) - else: - u = _pseudorandom("".join(map(chr, u))) - rv = starmap(xor, zip(rv, u)) - buf.extend(rv) - if PY3: - return bytes(buf)[:keylen] - else: - return "".join(map(chr, buf))[:keylen] - - -def test(): - failed = [] - - def check(data, salt, iterations, keylen, expected): - rv = pbkdf2_hex(data, salt, iterations, keylen) - if rv != expected: - print("Test failed:") - print(" Expected: %s" % expected) - print(" Got: %s" % rv) - print(" Parameters:") - print(" data=%s" % data) - print(" salt=%s" % salt) - print(" iterations=%d" % iterations) - failed.append(1) - - # From RFC 6070 - check("password", "salt", 1, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6") - check("password", "salt", 2, 20, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957") - check("password", "salt", 4096, 20, "4b007901b765489abead49d926f721d065a429c1") - check( - "passwordPASSWORDpassword", - "saltSALTsaltSALTsaltSALTsaltSALTsalt", - 4096, - 25, - "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038", - ) - check("pass\x00word", "sa\x00lt", 4096, 16, "56fa6aa75548099dcc37d7f03425e0c3") - # This one is from the RFC but it just takes for ages - ##check('password', 'salt', 16777216, 20, - ## 'eefe3d61cd4da4e4e9945b3d6ba2158c2634e984') - - # From Crypt-PBKDF2 - check( - "password", "ATHENA.MIT.EDUraeburn", 1, 16, "cdedb5281bb2f801565a1122b2563515" - ) - check( - "password", - "ATHENA.MIT.EDUraeburn", - 1, - 32, - "cdedb5281bb2f801565a1122b25635150ad1f7a04bb9f3a333ecc0e2e1f70837", - ) - check( - "password", "ATHENA.MIT.EDUraeburn", 2, 16, "01dbee7f4a9e243e988b62c73cda935d" - ) - check( - "password", - "ATHENA.MIT.EDUraeburn", - 2, - 32, - "01dbee7f4a9e243e988b62c73cda935da05378b93244ec8f48a99e61ad799d86", - ) - check( - "password", - "ATHENA.MIT.EDUraeburn", - 1200, - 32, - "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddbc5e5142f708a31e2e62b1e13", - ) - check( - "X" * 64, - "pass phrase equals block size", - 1200, - 32, - "139c30c0966bc32ba55fdbf212530ac9c5ec59f1a452f5cc9ad940fea0598ed1", - ) - check( - "X" * 65, - "pass phrase exceeds block size", - 1200, - 32, - "9ccad6d468770cd51b10e6a68721be611a8b4d282601db3b36be9246915ec82a", - ) - - raise SystemExit(bool(failed)) - - -if __name__ == "__main__": - test() diff --git a/dev/remsh b/dev/remsh deleted file mode 100755 index 347a799d0..000000000 --- a/dev/remsh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# 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. - -if [ -z $NODE ]; then - if [ -z $1 ]; then - NODE=1 - else - NODE=$1 - fi -fi - -if [ -z $HOST ]; then - HOST="127.0.0.1" -fi - -NAME="remsh$$@$HOST" -NODE="node$NODE@$HOST" -erl -name $NAME -remsh $NODE -hidden diff --git a/dev/remsh-tls b/dev/remsh-tls deleted file mode 100755 index 089db669f..000000000 --- a/dev/remsh-tls +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# 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. - -if [ -z $NODE ]; then - if [ -z $1 ]; then - NODE=1 - else - NODE=$1 - fi -fi - -if [ -z $HOST ]; then - HOST="127.0.0.1" -fi - -NAME="remsh$$@$HOST" -NODE="node$NODE@$HOST" -rootdir="$(cd "${0%/*}" 2>/dev/null; echo "$PWD")" -erl -name $NAME -remsh $NODE -hidden -proto_dist inet_tls -ssl_dist_optfile "${rootdir}/couch_ssl_dist.conf" diff --git a/dev/run b/dev/run deleted file mode 100755 index 05ed16abb..000000000 --- a/dev/run +++ /dev/null @@ -1,862 +0,0 @@ -#!/usr/bin/env python3 -# -# 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. - -import atexit -import base64 -import contextlib -import functools -import glob -import inspect -import json -import ntpath -import optparse -import os -import posixpath -import re -import socket -import subprocess as sp -import sys -import time -import uuid -import traceback -from configparser import ConfigParser - -from pbkdf2 import pbkdf2_hex - -COMMON_SALT = uuid.uuid4().hex - -try: - from urllib.request import urlopen -except ImportError: - from urllib.request import urlopen - -try: - import http.client as httpclient -except ImportError: - import http.client as httpclient - - -def toposixpath(path): - if os.sep == ntpath.sep: - return path.replace(ntpath.sep, posixpath.sep) - else: - return path - - -def log(msg): - def decorator(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - def print_(chars): - if log.verbose: - sys.stdout.write(chars) - sys.stdout.flush() - - argnames = list(inspect.signature(func).parameters.keys()) - callargs = dict(list(zip(argnames, args))) - callargs.update(kwargs) - print_("[ * ] " + msg.format(**callargs) + " ... ") - try: - res = func(*args, **kwargs) - except KeyboardInterrupt: - print_("ok\n") - except Exception as err: - print_("failed: %s\n" % err) - raise - else: - print_("ok\n") - return res - - return wrapper - - return decorator - - -log.verbose = True - - -def main(): - ctx = setup() - startup(ctx) - if ctx["cmd"]: - run_command(ctx, ctx["cmd"]) - else: - join(ctx, cluster_port(ctx, 1), *ctx["admin"]) - - -def setup(): - opts, args = setup_argparse() - ctx = setup_context(opts, args) - setup_logging(ctx) - setup_dirs(ctx) - check_beams(ctx) - check_boot_script(ctx) - setup_configs(ctx) - return ctx - - -def setup_logging(ctx): - log.verbose = ctx["verbose"] - - -def setup_argparse(): - parser = get_args_parser() - return parser.parse_args() - - -def get_args_parser(): - parser = optparse.OptionParser(description="Runs CouchDB 2.0 dev cluster") - parser.add_option( - "-a", - "--admin", - metavar="USER:PASS", - default=None, - help="Add an admin account to the development cluster", - ) - parser.add_option( - "-n", - "--nodes", - metavar="nodes", - default=3, - type=int, - help="Number of development nodes to be spun up", - ) - parser.add_option( - "-q", - "--quiet", - action="store_false", - dest="verbose", - default=True, - help="Don't print anything to STDOUT", - ) - parser.add_option( - "--with-admin-party-please", - dest="with_admin_party", - default=False, - action="store_true", - help="Runs a dev cluster with admin party mode on", - ) - parser.add_option( - "--enable-erlang-views", - action="store_true", - help="Enables the Erlang view server", - ) - parser.add_option( - "--no-join", - dest="no_join", - default=False, - action="store_true", - help="Do not join nodes on boot", - ) - parser.add_option( - "--with-haproxy", - dest="with_haproxy", - default=False, - action="store_true", - help="Use HAProxy", - ) - parser.add_option( - "--haproxy", dest="haproxy", default="haproxy", help="HAProxy executable path" - ) - parser.add_option( - "--haproxy-port", dest="haproxy_port", default="5984", help="HAProxy port" - ) - parser.add_option( - "--node-number", - dest="node_number", - type=int, - default=1, - help="The node number to seed them when creating the node(s)", - ) - parser.add_option( - "-c", - "--config-overrides", - action="append", - default=[], - help="Optional key=val config overrides. Can be repeated", - ) - parser.add_option( - "--erlang-config", - dest="erlang_config", - default="rel/files/sys.config", - help="Specify an alternative Erlang application configuration", - ) - parser.add_option( - "--degrade-cluster", - dest="degrade_cluster", - type=int, - default=0, - help="The number of nodes that should be stopped after cluster config", - ) - parser.add_option( - "--no-eval", - action="store_true", - default=False, - help="Do not eval subcommand output", - ) - parser.add_option( - "--auto-ports", - dest="auto_ports", - default=False, - action="store_true", - help="Select available ports for nodes automatically", - ) - parser.add_option( - "--extra_args", - dest="extra_args", - default=None, - help="Extra arguments to pass to beam process", - ) - parser.add_option( - "-l", - "--locald-config", - dest="locald_configs", - action="append", - default=[], - help="Path to config to place in 'local.d'. Can be repeated", - ) - return parser - - -def setup_context(opts, args): - fpath = os.path.abspath(__file__) - return { - "N": opts.nodes, - "no_join": opts.no_join, - "with_admin_party": opts.with_admin_party, - "enable_erlang_views": opts.enable_erlang_views, - "admin": opts.admin.split(":", 1) if opts.admin else None, - "nodes": ["node%d" % (i + opts.node_number) for i in range(opts.nodes)], - "node_number": opts.node_number, - "degrade_cluster": opts.degrade_cluster, - "devdir": os.path.dirname(fpath), - "rootdir": os.path.dirname(os.path.dirname(fpath)), - "cmd": " ".join(args), - "verbose": opts.verbose, - "with_haproxy": opts.with_haproxy, - "haproxy": opts.haproxy, - "haproxy_port": opts.haproxy_port, - "config_overrides": opts.config_overrides, - "erlang_config": opts.erlang_config, - "no_eval": opts.no_eval, - "extra_args": opts.extra_args, - "reset_logs": True, - "procs": [], - "auto_ports": opts.auto_ports, - "locald_configs": opts.locald_configs, - } - - -@log("Setup environment") -def setup_dirs(ctx): - ensure_dir_exists(ctx["devdir"], "logs") - - -def ensure_dir_exists(root, *segments): - path = os.path.join(root, *segments) - if not os.path.exists(path): - os.makedirs(path) - return path - - -@log("Ensure CouchDB is built") -def check_beams(ctx): - for fname in glob.glob(os.path.join(ctx["devdir"], "*.erl")): - sp.check_call(["erlc", "-o", ctx["devdir"] + os.sep, fname]) - - -@log("Ensure Erlang boot script exists") -def check_boot_script(ctx): - if not os.path.exists(os.path.join(ctx["devdir"], "devnode.boot")): - env = os.environ.copy() - env["ERL_LIBS"] = os.path.join(ctx["rootdir"], "src") - sp.check_call(["escript", "make_boot_script"], env=env, cwd=ctx["devdir"]) - - -@log("Prepare configuration files") -def setup_configs(ctx): - for idx, node in enumerate(ctx["nodes"]): - cluster_port, backend_port, prometheus_port = get_ports( - ctx, idx + ctx["node_number"] - ) - env = { - "prefix": toposixpath(ctx["rootdir"]), - "package_author_name": "The Apache Software Foundation", - "data_dir": toposixpath( - ensure_dir_exists(ctx["devdir"], "lib", node, "data") - ), - "view_index_dir": toposixpath( - ensure_dir_exists(ctx["devdir"], "lib", node, "data") - ), - "state_dir": toposixpath( - ensure_dir_exists(ctx["devdir"], "lib", node, "data") - ), - "node_name": "-name %s@127.0.0.1" % node, - "cluster_port": cluster_port, - "backend_port": backend_port, - "prometheus_port": prometheus_port, - "uuid": "fake_uuid_for_dev", - "_default": "", - } - write_config(ctx, node, env) - write_locald_configs(ctx, node, env) - generate_haproxy_config(ctx) - - -def write_locald_configs(ctx, node, env): - for locald_config in ctx["locald_configs"]: - config_src = os.path.join(ctx["rootdir"], locald_config) - if os.path.exists(config_src): - config_filename = os.path.basename(config_src) - config_tgt = os.path.join( - ctx["devdir"], "lib", node, "etc", "local.d", config_filename - ) - with open(config_src) as handle: - content = handle.read() - with open(config_tgt, "w") as handle: - handle.write(content) - - -def generate_haproxy_config(ctx): - haproxy_config = os.path.join(ctx["devdir"], "lib", "haproxy.cfg") - template = os.path.join(ctx["rootdir"], "rel", "haproxy.cfg") - - with open(template) as handle: - config = handle.readlines() - - out = [] - for line in config: - match = re.match("(.*?)<<(.*?)>>(.*?)", line, re.S) - if match: - prefix, template, suffix = match.groups() - for node in ctx["nodes"]: - node_idx = int(node.replace("node", "")) - text = template.format( - **{"node_idx": node_idx, "port": cluster_port(ctx, node_idx)} - ) - out.append(prefix + text + suffix) - else: - out.append(line) - - with open(haproxy_config, "w") as handle: - handle.write("\n".join(out)) - - -def apply_config_overrides(ctx, content): - for kv_str in ctx["config_overrides"]: - key, val = kv_str.split("=") - key, val = key.strip(), val.strip() - match = "[;=]{0,2}%s.*" % key - repl = "%s = %s" % (key, val) - content = re.sub(match, repl, content) - return content - - -def get_ports(ctx, idnode): - assert idnode - if idnode <= 5 and not ctx["auto_ports"]: - return ( - (10000 * idnode) + 5984, - (10000 * idnode) + 5986, - (10000 * idnode) + 7986, - ) - else: - return tuple(get_available_ports(2)) - - -def get_available_ports(num): - ports = [] - while len(ports) < num + 1: - with contextlib.closing( - socket.socket(socket.AF_INET, socket.SOCK_STREAM) - ) as soc: - soc.bind(("localhost", 0)) - _, port = soc.getsockname() - if port not in ports: - ports.append(port) - return ports - - -def get_node_config(ctx, node_idx): - node = "node{}".format(node_idx) - config_dir = os.path.join(ctx["devdir"], "lib", node, "etc") - config = ConfigParser() - config.read( - [os.path.join(config_dir, "default.ini"), os.path.join(config_dir, "local.ini")] - ) - return config - - -def backend_port(ctx, n): - return int(get_node_config(ctx, n).get("httpd", "port")) - - -def cluster_port(ctx, n): - return int(get_node_config(ctx, n).get("chttpd", "port")) - - -def write_config(ctx, node, env): - etc_src = os.path.join(ctx["rootdir"], "rel", "overlay", "etc") - etc_tgt = ensure_dir_exists(ctx["devdir"], "lib", node, "etc") - - for fname in glob.glob(os.path.join(etc_src, "*")): - base = os.path.basename(fname) - tgt = os.path.join(etc_tgt, base) - - if os.path.isdir(fname): - continue - - with open(fname) as handle: - content = handle.read() - - for key in env: - content = re.sub("{{%s}}" % key, str(env[key]), content) - - if base == "default.ini": - content = hack_default_ini(ctx, node, content) - content = apply_config_overrides(ctx, content) - elif base == "local.ini": - content = hack_local_ini(ctx, content) - - with open(tgt, "w") as handle: - handle.write(content) - - ensure_dir_exists(etc_tgt, "local.d") - - -def boot_haproxy(ctx): - if not ctx["with_haproxy"]: - return - config = os.path.join(ctx["devdir"], "lib", "haproxy.cfg") - cmd = [ctx["haproxy"], "-f", config] - logfname = os.path.join(ctx["devdir"], "logs", "haproxy.log") - log = open(logfname, "w") - env = os.environ.copy() - if "HAPROXY_PORT" not in env: - env["HAPROXY_PORT"] = ctx["haproxy_port"] - return sp.Popen( - " ".join(cmd), shell=True, stdin=sp.PIPE, stdout=log, stderr=sp.STDOUT, env=env - ) - - -def hack_default_ini(ctx, node, contents): - - contents = re.sub( - "^\[httpd\]$", - "[httpd]\nenable = true", - contents, - flags=re.MULTILINE, - ) - - if ctx["enable_erlang_views"]: - contents = re.sub( - "^\[native_query_servers\]$", - "[native_query_servers]\nerlang = {couch_native_process, start_link, []}", - contents, - flags=re.MULTILINE, - ) - contents = re.sub("n=3", "n=%s" % ctx["N"], contents) - return contents - - -def hack_local_ini(ctx, contents): - # make sure all three nodes have the same secret - secret_line = "secret = %s\n" % COMMON_SALT - previous_line = "; require_valid_user = false\n" - contents = contents.replace(previous_line, previous_line + secret_line) - - if ctx["with_admin_party"]: - os.environ["COUCHDB_TEST_ADMIN_PARTY_OVERRIDE"] = "1" - ctx["admin"] = ("Admin Party!", "You do not need any password.") - return contents - - # handle admin credentials passed from cli or generate own one - if ctx["admin"] is None: - ctx["admin"] = user, pswd = "root", gen_password() - else: - user, pswd = ctx["admin"] - - return contents + "\n%s = %s" % (user, hashify(pswd)) - - -def gen_password(): - # TODO: figure how to generate something more friendly here - return base64.b64encode(os.urandom(6)).decode() - - -def hashify(pwd, salt=COMMON_SALT, iterations=10, keylen=20): - """ - Implements password hashing according to: - - https://issues.apache.org/jira/browse/COUCHDB-1060 - - https://issues.apache.org/jira/secure/attachment/12492631/0001-Integrate-PBKDF2.patch - - This test uses 'candeira:candeira' - - >>> hashify(candeira) - -pbkdf2-99eb34d97cdaa581e6ba7b5386e112c265c5c670,d1d2d4d8909c82c81b6c8184429a0739,10 - """ - derived_key = pbkdf2_hex(pwd, salt, iterations, keylen) - return "-pbkdf2-%s,%s,%s" % (derived_key, salt, iterations) - - -def startup(ctx): - atexit.register(kill_processes, ctx) - boot_nodes(ctx) - ensure_all_nodes_alive(ctx) - if ctx["no_join"]: - return - if ctx["with_admin_party"]: - cluster_setup_with_admin_party(ctx) - else: - cluster_setup(ctx) - if ctx["degrade_cluster"] > 0: - degrade_cluster(ctx) - - -def kill_processes(ctx): - for proc in ctx["procs"]: - if proc and proc.returncode is None: - proc.kill() - - -def degrade_cluster(ctx): - if ctx["with_haproxy"]: - haproxy_proc = ctx["procs"].pop() - for i in range(0, ctx["degrade_cluster"]): - proc = ctx["procs"].pop() - if proc is not None: - kill_process(proc) - if ctx["with_haproxy"]: - ctx["procs"].append(haproxy_proc) - - -@log("Stoping proc {proc.pid}") -def kill_process(proc): - if proc and proc.returncode is None: - proc.kill() - - -def boot_nodes(ctx): - for node in ctx["nodes"]: - ctx["procs"].append(boot_node(ctx, node)) - haproxy_proc = boot_haproxy(ctx) - if haproxy_proc is not None: - ctx["procs"].append(haproxy_proc) - - -def ensure_all_nodes_alive(ctx): - status = dict((num, False) for num in list(range(ctx["N"]))) - for _ in range(10): - for num in range(ctx["N"]): - if status[num]: - continue - local_port = cluster_port(ctx, num + 1) - url = "http://127.0.0.1:{0}/".format(local_port) - try: - check_node_alive(url) - except: - pass - else: - status[num] = True - if all(status.values()): - return - time.sleep(1) - if not all(status.values()): - print("Failed to start all the nodes." " Check the dev/logs/*.log for errors.") - sys.exit(1) - - -@log("Check node at {url}") -def check_node_alive(url): - error = None - for _ in range(10): - try: - with contextlib.closing(urlopen(url)): - pass - except Exception as exc: - error = exc - time.sleep(1) - else: - error = None - break - if error is not None: - raise error - - -def set_boot_env(ctx): - - # fudge fauxton path - if os.path.exists("src/fauxton/dist/release"): - fauxton_root = "src/fauxton/dist/release" - else: - fauxton_root = "share/www" - - os.environ["COUCHDB_FAUXTON_DOCROOT"] = fauxton_root - - # fudge default query server paths - couchjs = os.path.join(ctx["rootdir"], "src", "couch", "priv", "couchjs") - mainjs = os.path.join(ctx["rootdir"], "share", "server", "main.js") - coffeejs = os.path.join(ctx["rootdir"], "share", "server", "main-coffee.js") - - qs_javascript = toposixpath("%s %s" % (couchjs, mainjs)) - qs_coffescript = toposixpath("%s %s" % (couchjs, coffeejs)) - - os.environ["COUCHDB_QUERY_SERVER_JAVASCRIPT"] = qs_javascript - os.environ["COUCHDB_QUERY_SERVER_COFFEESCRIPT"] = qs_coffescript - - -@log("Start node {node}") -def boot_node(ctx, node): - set_boot_env(ctx) - env = os.environ.copy() - env["ERL_LIBS"] = os.path.join(ctx["rootdir"], "src") - - node_etcdir = os.path.join(ctx["devdir"], "lib", node, "etc") - reldir = os.path.join(ctx["rootdir"], "rel") - - cmd = [ - "erl", - "-args_file", - os.path.join(node_etcdir, "vm.args"), - "-config", - os.path.join(ctx["rootdir"], ctx["erlang_config"]), - "-couch_ini", - os.path.join(node_etcdir, "default.ini"), - os.path.join(node_etcdir, "local.ini"), - os.path.join(node_etcdir, "local.d"), - "-reltool_config", - os.path.join(reldir, "reltool.config"), - "-parent_pid", - str(os.getpid()), - "-boot", - os.path.join(ctx["devdir"], "devnode"), - "-pa", - ctx["devdir"], - "-s monitor_parent", - ] - if ctx["reset_logs"]: - mode = "wb" - else: - mode = "r+b" - logfname = os.path.join(ctx["devdir"], "logs", "%s.log" % node) - log = open(logfname, mode) - if "extra_args" in ctx and ctx["extra_args"]: - cmd += ctx["extra_args"].split(" ") - cmd = [toposixpath(x) for x in cmd] - return sp.Popen(cmd, stdin=sp.PIPE, stdout=log, stderr=sp.STDOUT, env=env) - - -@log("Running cluster setup") -def cluster_setup(ctx): - lead_port = cluster_port(ctx, 1) - if enable_cluster(ctx["N"], lead_port, *ctx["admin"]): - for num in range(1, ctx["N"]): - node_port = cluster_port(ctx, num + 1) - node_name = ctx["nodes"][num] - enable_cluster(ctx["N"], node_port, *ctx["admin"]) - add_node(lead_port, node_name, node_port, *ctx["admin"]) - finish_cluster(lead_port, *ctx["admin"]) - return lead_port - - -def enable_cluster(node_count, port, user, pswd): - conn = httpclient.HTTPConnection("127.0.0.1", port) - conn.request( - "POST", - "/_cluster_setup", - json.dumps( - { - "action": "enable_cluster", - "bind_address": "0.0.0.0", - "username": user, - "password": pswd, - "node_count": node_count, - } - ), - { - "Authorization": basic_auth_header(user, pswd), - "Content-Type": "application/json", - }, - ) - resp = conn.getresponse() - if resp.status == 400: - resp.close() - return False - assert resp.status == 201, resp.read() - resp.close() - return True - - -def add_node(lead_port, node_name, node_port, user, pswd): - conn = httpclient.HTTPConnection("127.0.0.1", lead_port) - conn.request( - "POST", - "/_cluster_setup", - json.dumps( - { - "action": "add_node", - "host": "127.0.0.1", - "port": node_port, - "name": node_name, - "username": user, - "password": pswd, - } - ), - { - "Authorization": basic_auth_header(user, pswd), - "Content-Type": "application/json", - }, - ) - resp = conn.getresponse() - assert resp.status in (201, 409), resp.read() - resp.close() - - -def set_cookie(port, user, pswd): - conn = httpclient.HTTPConnection("127.0.0.1", port) - conn.request( - "POST", - "/_cluster_setup", - json.dumps({"action": "receive_cookie", "cookie": generate_cookie()}), - { - "Authorization": basic_auth_header(user, pswd), - "Content-Type": "application/json", - }, - ) - resp = conn.getresponse() - assert resp.status == 201, resp.read() - resp.close() - - -def finish_cluster(port, user, pswd): - conn = httpclient.HTTPConnection("127.0.0.1", port) - conn.request( - "POST", - "/_cluster_setup", - json.dumps({"action": "finish_cluster"}), - { - "Authorization": basic_auth_header(user, pswd), - "Content-Type": "application/json", - }, - ) - resp = conn.getresponse() - # 400 for already set up'ed cluster - assert resp.status in (201, 400), resp.read() - resp.close() - - -def basic_auth_header(user, pswd): - return "Basic " + base64.b64encode((user + ":" + pswd).encode()).decode() - - -def generate_cookie(): - return base64.b64encode(os.urandom(12)).decode() - - -def cluster_setup_with_admin_party(ctx): - connect_nodes(ctx) - host, port = "127.0.0.1", cluster_port(ctx, 1) - create_system_databases(host, port) - - -def connect_nodes(ctx): - host, port = "127.0.0.1", backend_port(ctx, 1) - for node in ctx["nodes"]: - path = "/_nodes/%s@127.0.0.1" % node - try_request( - host, - port, - "PUT", - path, - (200, 201, 202, 409), - body="{}", - error="Failed to join %s into cluster:\n" % node, - ) - - -def try_request( - host, port, meth, path, success_codes, body=None, retries=10, retry_dt=1, error="" -): - while True: - conn = httpclient.HTTPConnection(host, port) - conn.request(meth, path, body=body) - resp = conn.getresponse() - if resp.status in success_codes: - return resp.status, resp.read() - elif retries <= 0: - assert resp.status in success_codes, "%s%s" % (error, resp.read()) - retries -= 1 - time.sleep(retry_dt) - - -def create_system_databases(host, port): - for dbname in ["_users", "_replicator", "_global_changes"]: - conn = httpclient.HTTPConnection(host, port) - conn.request("HEAD", "/" + dbname) - resp = conn.getresponse() - if resp.status == 404: - try_request( - host, - port, - "PUT", - "/" + dbname, - (201, 202, 412), - error="Failed to create '%s' database:\n" % dbname, - ) - - -@log( - "Developers cluster is set up at http://127.0.0.1:{lead_port}.\n" - "Admin username: {user}\n" - "Password: {password}\n" - "Time to hack!" -) -def join(ctx, lead_port, user, password): - while True: - for proc in ctx["procs"]: - if proc is not None and proc.returncode is not None: - exit(1) - time.sleep(2) - - -@log("Exec command {cmd}") -def run_command(ctx, cmd): - if ctx["no_eval"]: - p = sp.Popen(cmd, shell=True) - p.wait() - exit(p.returncode) - else: - p = sp.Popen(cmd, shell=True, stdout=sp.PIPE, stderr=sys.stderr) - while True: - line = p.stdout.readline() - if not line: - break - eval(line) - p.wait() - exit(p.returncode) - - -@log("Restart all nodes") -def reboot_nodes(ctx): - ctx["reset_logs"] = False - kill_processes(ctx) - boot_nodes(ctx) - ensure_all_nodes_alive(ctx) - - -if __name__ == "__main__": - try: - main() - except KeyboardInterrupt: - pass diff --git a/dev/run.cmd b/dev/run.cmd deleted file mode 100644 index 14ce2276c..000000000 --- a/dev/run.cmd +++ /dev/null @@ -1,15 +0,0 @@ -@ECHO OFF - -:: 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. - -python %~dp0\run %* diff --git a/erlang_ls.config b/erlang_ls.config deleted file mode 100644 index 94483cfec..000000000 --- a/erlang_ls.config +++ /dev/null @@ -1,5 +0,0 @@ -apps_dirs: - - "src/*" -include_dirs: - - "src" - - "src/*/include" diff --git a/make.cmd b/make.cmd deleted file mode 100644 index bf8677898..000000000 --- a/make.cmd +++ /dev/null @@ -1,3 +0,0 @@ -@ECHO OFF - -make.exe -f Makefile.win %* diff --git a/mix.exs b/mix.exs deleted file mode 100644 index 577a20491..000000000 --- a/mix.exs +++ /dev/null @@ -1,162 +0,0 @@ -defmodule CoverTool do - def start(path, options) do - {dirs, options} = Keyword.pop(options, :dirs, []) - fun = ExCoveralls.start(path, options) - Mix.shell().info("Cover compiling modules ...") - :cover.stop() - :cover.start() - - Enum.each(dirs, fn path -> - path - |> Path.expand(__DIR__) - |> String.to_charlist() - |> :cover.compile_beam_directory() - end) - - ExCoveralls.ConfServer.start() - ExCoveralls.ConfServer.set(options) - ExCoveralls.StatServer.start() - fun - end -end - -defmodule Mix.Tasks.Suite do - @moduledoc """ - Helper task to create `suites.elixir` file. It suppose to be used as follows - ``` - MIX_ENV=integration mix suite > test/elixir/test/config/suite.elixir - ``` - """ - use Mix.Task - @shortdoc "Outputs all availabe integration tests" - def run(_) do - Path.wildcard(Path.join(Mix.Project.build_path(), "/**/ebin")) - |> Enum.filter(&File.dir?/1) - |> Enum.map(&Code.append_path/1) - - tests = - Couch.Test.Suite.list() - |> Enum.sort() - |> Couch.Test.Suite.group_by() - - IO.puts(Couch.Test.Suite.pretty_print(tests)) - end -end - -defmodule CouchDBTest.Mixfile do - use Mix.Project - - def project do - [ - app: :couchdbtest, - version: "0.1.0", - elixir: "~> 1.5", - lockfile: Path.expand("mix.lock", __DIR__), - deps_path: Path.expand("src", __DIR__), - build_path: Path.expand("_build", __DIR__), - compilers: [:elixir, :app], - start_permanent: Mix.env() == :prod, - build_embedded: Mix.env() == :prod, - deps: deps(), - consolidate_protocols: Mix.env() not in [:test, :dev, :integration], - test_paths: get_test_paths(Mix.env()), - elixirc_paths: elixirc_paths(Mix.env()), - test_coverage: [ - tool: CoverTool, - dirs: get_coverage_paths(), - type: "html" - ] - ] - end - - # Run "mix help compile.app" to learn about applications. - def application do - [ - extra_applications: [:logger], - applications: [:httpotion] - ] - end - - # Specifies which paths to compile per environment. - defp elixirc_paths(:test), do: ["test/elixir/lib", "test/elixir/test/support"] - defp elixirc_paths(:integration), do: ["test/elixir/lib", "test/elixir/test/support"] - defp elixirc_paths(_), do: ["test/elixir/lib"] - - # Run "mix help deps" to learn about dependencies. - defp deps() do - [ - {:junit_formatter, "~> 3.0", only: [:dev, :test, :integration]}, - {:httpotion, ">= 3.1.3", only: [:dev, :test, :integration], runtime: false}, - {:excoveralls, "~> 0.12", only: :test}, - {:b64url, path: Path.expand("src/b64url", __DIR__)}, - {:jiffy, path: Path.expand("src/jiffy", __DIR__)}, - {:jwtf, path: Path.expand("src/jwtf", __DIR__)}, - {:ibrowse, - path: Path.expand("src/ibrowse", __DIR__), override: true, compile: false}, - {:credo, "~> 1.5.6", only: [:dev, :test, :integration], runtime: false} - ] - end - - def get_test_paths(:test) do - Path.wildcard("src/*/test/exunit") |> Enum.filter(&File.dir?/1) - end - - def get_test_paths(:integration) do - integration_tests = - Path.wildcard("src/*/test/integration") |> Enum.filter(&File.dir?/1) - - ["test/elixir/test" | integration_tests] - end - - def get_test_paths(_) do - [] - end - - defp get_deps_paths() do - deps = [ - "bunt", - "certifi", - "credo", - "excoveralls", - "hackney", - "httpotion", - "ibrowse", - "idna", - "jason", - "jiffy", - "junit_formatter", - "metrics", - "mimerl", - "parse_trans", - "ssl_verify_fun", - "unicode_util_compat", - "b64url", - "bear", - "mochiweb", - "snappy", - "rebar", - "proper", - "mochiweb", - "meck", - "khash", - "hyper", - "fauxton", - "folsom", - "hqueue" - ] - - deps |> Enum.map(fn app -> "src/#{app}" end) - end - - defp get_coverage_paths() do - deps = - get_deps_paths() - |> Enum.reduce(MapSet.new(), fn x, set -> - MapSet.put(set, "#{x}/ebin") - end) - - Path.wildcard("src/*/ebin") - |> Enum.filter(&File.dir?/1) - |> Enum.filter(fn path -> not MapSet.member?(deps, path) end) - end -end diff --git a/mix.lock b/mix.lock deleted file mode 100644 index 48e7c719f..000000000 --- a/mix.lock +++ /dev/null @@ -1,19 +0,0 @@ -%{ - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, - "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "805abd97539caf89ec6d4732c91e62ba9da0cda51ac462380bbd28ee697a8c42"}, - "credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"}, - "excoveralls": {:hex, :excoveralls, "0.12.1", "a553c59f6850d0aff3770e4729515762ba7c8e41eedde03208182a8dc9d0ce07", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "5c1f717066a299b1b732249e736c5da96bb4120d1e55dc2e6f442d251e18a812"}, - "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "e0100f8ef7d1124222c11ad362c857d3df7cb5f4204054f9f0f4a728666591fc"}, - "httpotion": {:hex, :httpotion, "3.1.3", "fdaf1e16b9318dcb722de57e75ac368c93d4c6e3c9125f93e960f953a750fb77", [:mix], [{:ibrowse, "== 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: false]}], "hexpm", "e420172ef697a0f1f4dc40f89a319d5a3aad90ec51fa424f08c115f04192ae43"}, - "ibrowse": {:hex, :ibrowse, "4.4.0", "2d923325efe0d2cb09b9c6a047b2835a5eda69d8a47ed6ff8bc03628b764e991", [:rebar3], [], "hexpm"}, - "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"}, - "jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"}, - "jiffy": {:hex, :jiffy, "0.15.2", "de266c390111fd4ea28b9302f0bc3d7472468f3b8e0aceabfbefa26d08cd73b7", [:rebar3], [], "hexpm"}, - "junit_formatter": {:hex, :junit_formatter, "3.0.0", "13950d944dbd295da7d8cc4798b8faee808a8bb9b637c88069954eac078ac9da", [:mix], [], "hexpm", "d77b7b9a1601185b18dfe7682b27c46d5d12721f12fdc75180a6fc573b4e64b1"}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.5", "6eaf7ad16cb568bb01753dbbd7a95ff8b91c7979482b95f38443fe2c8852a79b", [:make, :mix, :rebar3], [], "hexpm", "13104d7897e38ed7f044c4de953a6c28597d1c952075eb2e328bc6d6f2bfc496"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm", "1d1848c40487cdb0b30e8ed975e34e025860c02e419cb615d255849f3427439d"}, -} diff --git a/rebar.config.script b/rebar.config.script deleted file mode 100644 index 31855098b..000000000 --- a/rebar.config.script +++ /dev/null @@ -1,220 +0,0 @@ -%% -*- erlang -*- -% 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. - -% -% Blacklist some bad releases. -% -{ok, Version} = file:read_file(filename:join( - [code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"] -)). - -% Version may be binary if file has /n at end :( -% there is no string:trim/1 in Erlang 19 :( -VerString = case Version of - V when is_binary(V) -> string:strip(binary_to_list(V), right, $\n); - _ -> string:strip(Version, right, $\n) -end. -VerList = lists:map(fun(X) -> {Int, _} = string:to_integer(X), Int end, - string:tokens(VerString, ".")). - -DisplayMsg = fun(Msg, Args) -> - Base = iolist_to_binary(io_lib:format(Msg, Args)), - Lines = binary:split(Base, <<"\n">>, [global]), - MaxLen = lists:foldl(fun(Line, Acc) -> - max(Acc, size(Line)) - end, 0, Lines), - Decoration = iolist_to_binary(["*" || _ <- lists:seq(1, MaxLen)]), - ReNewLined = [[L, "~n"] || L <- Lines], - NewLines = ["~n", Decoration, "~n", ReNewLined, Decoration, "~n~n"], - MsgBin = iolist_to_binary(NewLines), - io:format(binary_to_list(MsgBin), []) -end. - -ErlangTooOld = fun(Ver) -> - DisplayMsg( - "This version of Erlang (~p) is too old for use with Apache CouchDB.~n~n" - "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n" - "for the latest information on dependencies.", - [Ver] - ), - halt(1) -end. - -NotSupported = fun(Ver) -> - DisplayMsg( - "This version of Erlang (~p) is not officially supported by Apache~n" - "CouchDB. While we do not officially support this version, there~n" - "are also no known bugs or incompatibilities.~n~n" - "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n" - "for the latest information on dependencies.", - [Ver] - ) -end. - -BadErlang = fun(Ver) -> - DisplayMsg( - "This version of Erlang (~p) is known to contain bugs that directly~n" - "affect the correctness of Apache CouchDB.~n~n" - "You should *NOT* use this version of Erlang.~n~n" - "See https://docs.couchdb.org/en/stable/install/unix.html#dependencies~n" - "for the latest information on dependencies.", - [Ver] - ), - case os:getenv("TRAVIS") of - "true" -> - io:fwrite("Travis run, ignoring bad release. You have been warned!~n"), - ok; - _ -> - halt(1) - end -end. - -case VerList of - [OldVer | _] when OldVer < 19 -> ErlangTooOld(VerString); - - [19 | _] -> NotSupported(VerString); - - [20 | _] = V20 when V20 < [20, 3, 8, 11] -> BadErlang(VerString); - [21 | _] = V21 when V21 < [21, 2, 3] -> BadErlang(VerString); - [22, 0, N | _] when N < 5 -> BadErlang(VerString); - - _ -> ok -end. - -% Set the path to the configuration environment generated -% by `./configure`. - -COUCHDB_ROOT = filename:dirname(SCRIPT). -os:putenv("COUCHDB_ROOT", COUCHDB_ROOT). - -ConfigureEnv = filename:join(COUCHDB_ROOT, "config.erl"). -os:putenv("COUCHDB_CONFIG", ConfigureEnv). - -CouchConfig = case filelib:is_file(ConfigureEnv) of - true -> - {ok, Result} = file:consult(ConfigureEnv), - Result; - false -> - [] -end. - -os:putenv("COUCHDB_APPS_CONFIG_DIR", filename:join([COUCHDB_ROOT, "rel/apps"])). - -SubDirs = [ - %% must be compiled first as it has a custom behavior - "src/couch_epi", - "src/couch_log", - "src/chttpd", - "src/couch", - "src/couch_event", - "src/mem3", - "src/couch_index", - "src/couch_mrview", - "src/couch_replicator", - "src/couch_plugins", - "src/couch_pse_tests", - "src/couch_stats", - "src/couch_peruser", - "src/couch_tests", - "src/couch_dist", - "src/custodian", - "src/ddoc_cache", - "src/dreyfus", - "src/fabric", - "src/global_changes", - "src/ioq", - "src/jwtf", - "src/ken", - "src/mango", - "src/rexi", - "src/setup", - "src/smoosh", - "src/weatherreport", - "src/couch_prometheus", - "rel" -]. - -DepDescs = [ -%% Independent Apps -{config, "config", {tag, "2.1.9"}}, -{b64url, "b64url", {tag, "1.0.3"}}, -{ets_lru, "ets-lru", {tag, "1.1.0"}}, -{khash, "khash", {tag, "1.1.0"}}, -{snappy, "snappy", {tag, "CouchDB-1.0.7"}}, - -%% Non-Erlang deps -{docs, {url, "https://github.com/apache/couchdb-documentation"}, - {tag, "3.2.1-1"}, [raw]}, -{fauxton, {url, "https://github.com/apache/couchdb-fauxton"}, - {tag, "v1.2.8"}, [raw]}, -%% Third party deps -{folsom, "folsom", {tag, "CouchDB-0.8.4"}}, -{hyper, "hyper", {tag, "CouchDB-2.2.0-7"}}, -{ibrowse, "ibrowse", {tag, "CouchDB-4.4.2-5"}}, -{jiffy, "jiffy", {tag, "1.1.1"}}, -{mochiweb, "mochiweb", {tag, "v3.0.0"}}, -{meck, "meck", {tag, "0.9.2"}}, -{recon, "recon", {tag, "2.5.2"}} -]. - -WithProper = lists:keyfind(with_proper, 1, CouchConfig) == {with_proper, true}. - -OptionalDeps = case WithProper of - true -> - [{proper, {url, "https://github.com/proper-testing/proper"}, {tag, "v1.4"}}]; - false -> - [] -end. - -BaseUrl = "https://github.com/apache/". - -MakeDep = fun - ({AppName, {url, Url}, Version}) -> - {AppName, ".*", {git, Url, Version}}; - ({AppName, {url, Url}, Version, Options}) -> - {AppName, ".*", {git, Url, Version}, Options}; - ({AppName, RepoName, Version}) -> - Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git", - {AppName, ".*", {git, Url, Version}}; - ({AppName, RepoName, Version, Options}) -> - Url = BaseUrl ++ "couchdb-" ++ RepoName ++ ".git", - {AppName, ".*", {git, Url, Version}, Options} -end. - -AddConfig = [ - {require_otp_vsn, "20|21|22|23|24"}, - {deps_dir, "src"}, - {deps, lists:map(MakeDep, DepDescs ++ OptionalDeps)}, - {sub_dirs, SubDirs}, - {lib_dirs, ["src"]}, - {erl_opts, [{i, "../"}, {d, 'COUCHDB_ERLANG_VERSION', VerString}]}, - {eunit_opts, [verbose, {report,{eunit_surefire,[{dir,"."}]}}]}, - {plugins, [eunit_plugin]}, - {dialyzer, [ - {plt_location, local}, - {plt_location, COUCHDB_ROOT}, - {plt_extra_apps, [ - asn1, compiler, crypto, inets, kernel, runtime_tools, - sasl, setup, ssl, stdlib, syntax_tools, xmerl]}, - {warnings, [unmatched_returns, error_handling, race_conditions]}]}, - {post_hooks, [{compile, "escript support/build_js.escript"}]} -]. - -lists:foldl(fun({K, V}, CfgAcc) -> - case lists:keyfind(K, 1, CfgAcc) of - {K, Existent} when is_list(Existent) andalso is_list(V) -> - lists:keystore(K, 1, CfgAcc, {K, Existent ++ V}); - false -> - lists:keystore(K, 1, CfgAcc, {K, V}) - end -end, CONFIG, AddConfig). diff --git a/rel/apps/config.config b/rel/apps/config.config deleted file mode 100644 index 0cbc1c58e..000000000 --- a/rel/apps/config.config +++ /dev/null @@ -1,4 +0,0 @@ -{sensitive, #{ - "admins" => all, - "replicator" => ["password"] -}}. diff --git a/rel/apps/couch_epi.config b/rel/apps/couch_epi.config deleted file mode 100644 index a53721a48..000000000 --- a/rel/apps/couch_epi.config +++ /dev/null @@ -1,22 +0,0 @@ -% 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. - -{plugins, [ - couch_db_epi, - chttpd_epi, - couch_index_epi, - dreyfus_epi, - global_changes_epi, - mango_epi, - mem3_epi, - setup_epi -]}. diff --git a/rel/boot_dev_cluster.sh b/rel/boot_dev_cluster.sh deleted file mode 100755 index 1dfeb5568..000000000 --- a/rel/boot_dev_cluster.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# 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. - -# Make log directory -mkdir -p ./rel/logs/ - -HAPROXY=`which haproxy` - -# Start each node -./rel/dev1/bin/couchdb > ./rel/logs/couchdb1.log 2>&1 & -DB1_PID=$! - -./rel/dev2/bin/couchdb > ./rel/logs/couchdb2.log 2>&1 & -DB2_PID=$! - -./rel/dev3/bin/couchdb > ./rel/logs/couchdb3.log 2>&1 & -DB3_PID=$! - -$HAPROXY -f rel/haproxy.cfg > ./rel/logs/haproxy.log 2>&1 & -HP_PID=$! - -sleep 2 - -# Connect the cluster -curl localhost:15986/nodes/dev2@127.0.0.1 -X PUT -d '{}' -curl localhost:15986/nodes/dev3@127.0.0.1 -X PUT -d '{}' - -trap "kill $DB1_PID $DB2_PID $DB3_PID $HP_PID" SIGINT SIGTERM SIGHUP - -wait diff --git a/rel/files/README b/rel/files/README deleted file mode 100644 index d22e2f086..000000000 --- a/rel/files/README +++ /dev/null @@ -1,18 +0,0 @@ -# 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. - -Ignore these files for now. - -This is to pacify newer rebar that insists on having a sys.config and -a vm.args in releases/$VSN/. - -eunit.ini is only for local testing so it is not copied into release diff --git a/rel/files/couchdb.cmd.in b/rel/files/couchdb.cmd.in deleted file mode 100644 index 244803bc8..000000000 --- a/rel/files/couchdb.cmd.in +++ /dev/null @@ -1,37 +0,0 @@ -@ECHO OFF - -:: 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. - -SET COUCHDB_BIN_DIR=%~dp0 -SET ROOTDIR=%COUCHDB_BIN_DIR%\..\ -CD "%ROOTDIR%" - -SET /P START_ERL= < releases\start_erl.data -FOR /F "tokens=1" %%G IN ("%START_ERL%") DO SET ERTS_VSN=%%G -FOR /F "tokens=2" %%G IN ("%START_ERL%") DO SET APP_VSN=%%G - -set BINDIR=%ROOTDIR%/erts-%ERTS_VSN%/bin -set EMU=beam -set PROGNAME=%~n0 -set PATH=%COUCHDB_BIN_DIR%;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\ - -IF NOT DEFINED COUCHDB_QUERY_SERVER_JAVASCRIPT SET COUCHDB_QUERY_SERVER_JAVASCRIPT={{prefix}}/bin/couchjs {{prefix}}/share/server/main.js -IF NOT DEFINED COUCHDB_QUERY_SERVER_COFFEESCRIPT SET COUCHDB_QUERY_SERVER_COFFEESCRIPT={{prefix}}/bin/couchjs {{prefix}}/share/server/main-coffee.js -IF NOT DEFINED COUCHDB_FAUXTON_DOCROOT SET COUCHDB_FAUXTON_DOCROOT={{fauxton_root}} - -"%BINDIR%\erl" -boot "%ROOTDIR%\releases\%APP_VSN%\couchdb" ^ --args_file "%ROOTDIR%\etc\vm.args" ^ --epmd "%BINDIR%\epmd.exe" ^ --config "%ROOTDIR%\releases\%APP_VSN%\sys.config" %* - -:: EXIT /B diff --git a/rel/files/couchdb.in b/rel/files/couchdb.in deleted file mode 100755 index 3ebb2e4ee..000000000 --- a/rel/files/couchdb.in +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/sh - -# 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. - -canonical_readlink () - { - FILE=$(dirname "$1")/$(basename "$1"); - if [ -h "$FILE" ]; then - cd $(dirname "$1") - canonical_readlink $(readlink "$FILE"); - else - cd "${1%/*}" && pwd -P; - fi -} -COUCHDB_BIN_DIR=$(canonical_readlink "$0") -ERTS_BIN_DIR=$COUCHDB_BIN_DIR/../ -cd "$COUCHDB_BIN_DIR/../" - -export ROOTDIR=${ERTS_BIN_DIR%/*} - -START_ERL=`cat "$ROOTDIR/releases/start_erl.data"` -ERTS_VSN=${START_ERL% *} -APP_VSN=${START_ERL#* } - -export BINDIR="$ROOTDIR/erts-$ERTS_VSN/bin" -export EMU=beam -export PROGNAME=`echo $0 | sed 's/.*\///'` - -export COUCHDB_QUERY_SERVER_JAVASCRIPT="${COUCHDB_QUERY_SERVER_JAVASCRIPT:-{{prefix}}/bin/couchjs {{prefix}}/share/server/main.js}" -export COUCHDB_QUERY_SERVER_COFFEESCRIPT="${COUCHDB_QUERY_SERVER_COFFEESCRIPT:-{{prefix}}/bin/couchjs {{prefix}}/share/server/main-coffee.js}" -# Use a separate var to work around rebar's mustache template bug -DEFAULT_FAUXTON_ROOT={{fauxton_root}} -export COUCHDB_FAUXTON_DOCROOT="${COUCHDB_FAUXTON_DOCROOT:-${DEFAULT_FAUXTON_ROOT}}" - -ARGS_FILE="${COUCHDB_ARGS_FILE:-$ROOTDIR/etc/vm.args}" -[ -n "${COUCHDB_INI_FILES:-}" ] && INI_ARGS="-couch_ini $COUCHDB_INI_FILES" -SYSCONFIG_FILE="${COUCHDB_SYSCONFIG_FILE:-$ROOTDIR/releases/$APP_VSN/sys.config}" - -exec "$BINDIR/erlexec" -boot "$ROOTDIR/releases/$APP_VSN/couchdb" \ - -args_file "${ARGS_FILE}" \ - ${INI_ARGS:-} \ - -config "${SYSCONFIG_FILE}" "$@" diff --git a/rel/files/eunit.config b/rel/files/eunit.config deleted file mode 100644 index 3c7457d3a..000000000 --- a/rel/files/eunit.config +++ /dev/null @@ -1,16 +0,0 @@ -% 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. - -[ - {kernel, [{error_logger, silent}]}, - {sasl, [{sasl_error_logger, false}]} -]. diff --git a/rel/files/eunit.ini b/rel/files/eunit.ini deleted file mode 100644 index 361ea6669..000000000 --- a/rel/files/eunit.ini +++ /dev/null @@ -1,38 +0,0 @@ -; Licensed to the Apache Software Foundation (ASF) under one -; or more contributor license agreements. See the NOTICE file -; distributed with this work for additional information -; regarding copyright ownership. The ASF licenses this file -; to you 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. - -[couchdb] -; time to relax! -uuid = 74696d6520746f2072656c617821 -default_security = everyone - -[httpd] -enable = true -port = 0 - -[chttpd] -port = 0 - -[log] -; log to a file to save our terminals from log spam -writer = file -file = couch.log -level = info - -[replicator] -; disable jitter to reduce test run times -startup_jitter = 0 \ No newline at end of file diff --git a/rel/files/sys.config b/rel/files/sys.config deleted file mode 100644 index 97562f561..000000000 --- a/rel/files/sys.config +++ /dev/null @@ -1,13 +0,0 @@ -% 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. - -[]. diff --git a/rel/files/vm.args b/rel/files/vm.args deleted file mode 100644 index 82b9fe5aa..000000000 --- a/rel/files/vm.args +++ /dev/null @@ -1,11 +0,0 @@ -# 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. diff --git a/rel/haproxy.cfg b/rel/haproxy.cfg deleted file mode 100644 index 540075761..000000000 --- a/rel/haproxy.cfg +++ /dev/null @@ -1,45 +0,0 @@ -# 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. - -global - maxconn 512 - spread-checks 5 - -defaults - mode http - log global - monitor-uri /_haproxy_health_check - option log-health-checks - option httplog - balance roundrobin - option forwardfor - option redispatch - retries 4 - option http-server-close - timeout client 150000 - timeout server 3600000 - timeout connect 500 - - stats enable - stats uri /_haproxy_stats - # stats auth admin:admin # Uncomment for basic auth - -frontend http-in - # This requires HAProxy 1.5.x - # bind *:$HAPROXY_PORT - bind *:5984 - default_backend couchdbs - -backend couchdbs - option httpchk GET /_up - http-check disable-on-404 - <> diff --git a/rel/overlay/bin/remsh b/rel/overlay/bin/remsh deleted file mode 100755 index de37d6cc2..000000000 --- a/rel/overlay/bin/remsh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/sh - -# 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. - -canonical_readlink () - { - FILE=$(dirname "$1")/$(basename "$1"); - if [ -h "$FILE" ]; then - cd $(dirname "$1") - canonical_readlink $(readlink "$FILE"); - else - cd "${1%/*}" && pwd -P; - fi -} -COUCHDB_BIN_DIR=$(canonical_readlink "$0") -ERTS_BIN_DIR=$COUCHDB_BIN_DIR/../ -ROOTDIR=${ERTS_BIN_DIR%/*} -START_ERL=$(cat "$ROOTDIR/releases/start_erl.data") -ERTS_VSN=${START_ERL% *} -APP_VSN=${START_ERL#* } -BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin - -PROGNAME=${0##*/} -VERBOSE="" -DEFAULT_NODE="couchdb@127.0.0.1" -LHOST=127.0.0.1 - -ARGS_FILE="${COUCHDB_ARGS_FILE:-$ROOTDIR/etc/vm.args}" - -# If present, extract cookie from ERL_FLAGS -# This is used by the CouchDB Dockerfile and Helm chart -NODE=$(echo "$ERL_FLAGS" | sed 's/^.*name \([^ ][^ ]*\).*$/\1/g') -if test -f "$ARGS_FILE"; then -# else attempt to extract from vm.args - ARGS_FILE_COOKIE=$(awk '$1=="-name"{print $2}' "$ARGS_FILE") - NODE="${NODE:-$ARGS_FILE_COOKIE}" -fi -NODE="${NODE:-$DEFAULT_NODE}" - -# If present, extract cookie from ERL_FLAGS -# This is used by the CouchDB Dockerfile and Helm chart -COOKIE=$(echo "$ERL_FLAGS" | sed 's/^.*setcookie \([^ ][^ ]*\).*$/\1/g') -if test -f "$ARGS_FILE"; then -# else attempt to extract from vm.args - ARGS_FILE_COOKIE=$(awk '$1=="-setcookie"{print $2}' "$ARGS_FILE") - COOKIE="${COOKIE:-$ARGS_FILE_COOKIE}" -fi - -printHelpAndExit() { - echo "Usage: ${PROGNAME} [OPTION]... [-- ]" - echo " -c cookie specify shared Erlang cookie" - echo " -l HOST specify remsh's host name (default: 127.0.0.1)" - echo " -m use output of \`hostname -f\` as remsh's host name" - echo " -n NAME@HOST specify couchdb's Erlang node name (-name in vm.args)" - echo " -v verbose; print invocation line" - echo " -t path/to/conf enable TLS distribution (customize in vm.args)" - echo " -h this help message" - exit -} - -while getopts ":hn:c:l:mvt:" optionName; do - case "$optionName" in - h) - printHelpAndExit 0 - ;; - n) - NODE=$OPTARG - ;; - c) - COOKIE=$OPTARG - ;; - l) - LHOST=$OPTARG - ;; - m) - LHOST=$(hostname -f) - ;; - v) - VERBOSE=0 - ;; - t) - TLSCONF=$OPTARG - if [ ! -f "$TLSCONF" ]; then - echo "ERROR: Could't find the file \"$TLSCONF\"." >&2 - exit 1 - fi - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - printHelpAndExit 0 - ;; - esac -done - -shift $((OPTIND - 1)) - -if [ ! -z "$VERBOSE" ]; then - # cheap but it works - set -x -fi - -# If present, strip -name or -setcookie from ERL_FLAGS -# to avoid conflicts with the cli parameters -ERL_FLAGS_CLEAN=$(echo "$ERL_FLAGS" | sed 's/-setcookie \([^ ][^ ]*\)//g' | sed 's/-name \([^ ][^ ]*\)//g') - -if [ -z "${COOKIE}" ]; then - echo "No Erlang cookie could be found, please specify with -c" >&2 - exit 1 -fi - -if [ -z "$TLSCONF" ]; then - exec env ERL_FLAGS="$ERL_FLAGS_CLEAN" "$BINDIR/erl" -boot "$ROOTDIR/releases/$APP_VSN/start_clean" \ - -name remsh$$@$LHOST -remsh $NODE -hidden -setcookie $COOKIE \ - "$@" -else - exec env ERL_FLAGS="$ERL_FLAGS_CLEAN" "$BINDIR/erl" -boot "$ROOTDIR/releases/$APP_VSN/start_clean" \ - -name remsh$$@$LHOST -remsh $NODE -hidden -setcookie $COOKIE \ - -proto_dist inet_tls -ssl_dist_optfile $TLSCONF \ - "$@" -fi diff --git a/rel/overlay/etc/default.d/README b/rel/overlay/etc/default.d/README deleted file mode 100644 index cae343ba4..000000000 --- a/rel/overlay/etc/default.d/README +++ /dev/null @@ -1,11 +0,0 @@ -CouchDB default configuration files - -Files found under the etc/default.d directory that end with .ini are -parsed within couchdb(1) at startup. - -This directory is intended for distribution-specific overrides of -CouchDB defaults. Package maintainers should be placing overrides in -this directory. - -System administrator should place overrides in the etc/local.d directory -instead. diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini deleted file mode 100644 index 162ccb926..000000000 --- a/rel/overlay/etc/default.ini +++ /dev/null @@ -1,749 +0,0 @@ -; Upgrading CouchDB will overwrite this file. -[vendor] -name = {{package_author_name}} - -[couchdb] -uuid = {{uuid}} -database_dir = {{data_dir}} -view_index_dir = {{view_index_dir}} -; util_driver_dir = -; plugin_dir = -;os_process_timeout = 5000 ; 5 seconds. for view servers. - -; Maximum number of .couch files to open at once. -; The actual limit may be slightly lower depending on how -; many schedulers you have as the allowance is divided evenly -; among them. -;max_dbs_open = 500 - -; Method used to compress everything that is appended to database and view index files, except -; for attachments (see the attachments section). Available methods are: -; -; none - no compression -; snappy - use google snappy, a very fast compressor/decompressor -; deflate_N - use zlib's deflate, N is the compression level which ranges from 1 (fastest, -; lowest compression ratio) to 9 (slowest, highest compression ratio) -;file_compression = snappy -; Higher values may give better read performance due to less read operations -; and/or more OS page cache hits, but they can also increase overall response -; time for writes when there are many attachment write requests in parallel. -;attachment_stream_buffer_size = 4096 -; Default security object for databases if not explicitly set -; everyone - same as couchdb 1.0, everyone can read/write -; admin_only - only admins can read/write -; admin_local - sharded dbs on :5984 are read/write for everyone, -; local dbs on :5986 are read/write for admins only -;default_security = admin_only -; btree_chunk_size = 1279 -; maintenance_mode = false -; stem_interactive_updates = true -; uri_file = -; The speed of processing the _changes feed with doc_ids filter can be -; influenced directly with this setting - increase for faster processing at the -; expense of more memory usage. -;changes_doc_ids_optimization_threshold = 100 -; Maximum document ID length. Can be set to an integer or 'infinity'. -;max_document_id_length = infinity -; -; Limit maximum document size. Requests to create / update documents with a body -; size larger than this will fail with a 413 http error. This limit applies to -; requests which update a single document as well as individual documents from -; a _bulk_docs request. The size limit is approximate due to the nature of JSON -; encoding. -;max_document_size = 8000000 ; bytes -; -; Maximum attachment size. -; max_attachment_size = 1073741824 ; 1 gibibyte -; -; Do not update the least recently used DB cache on reads, only writes -;update_lru_on_read = false -; -; The default storage engine to use when creating databases -; is set as a key into the [couchdb_engines] section. -;default_engine = couch -; -; Enable this to only "soft-delete" databases when DELETE /{db} requests are -; made. This will place a .recovery directory in your data directory and -; move deleted databases/shards there instead. You can then manually delete -; these files later, as desired. -;enable_database_recovery = false -; -; Set the maximum size allowed for a partition. This helps users avoid -; inadvertently abusing partitions resulting in hot shards. The default -; is 10GiB. A value of 0 or less will disable partition size checks. -;max_partition_size = 10737418240 -; -; When true, system databases _users and _replicator are created immediately -; on startup if not present. -;single_node = false - -; Allow edits on the _security object in the user db. By default, it's disabled. -;users_db_security_editable = false - -; Sets the maximum time that the coordinator node will wait for cluster members -; to request attachment data before returning a response to the client. -;attachment_writer_timeout = 300000 - -; Sets the log level for informational compaction related entries. -;compaction_log_level = info - -[purge] -; Allowed maximum number of documents in one purge request -;max_document_id_number = 100 -; -; Allowed maximum number of accumulated revisions in one purge request -;max_revisions_number = 1000 -; -; Allowed durations when index is not updated for local purge checkpoint -; document. Default is 24 hours. -;index_lag_warn_seconds = 86400 - -[couchdb_engines] -; The keys in this section are the filename extension that -; the specified engine module will use. This is important so -; that couch_server is able to find an existing database without -; having to ask every configured engine. -couch = couch_bt_engine - -[process_priority] -; Selectively disable altering process priorities for modules that request it. -; * NOTE: couch_server priority has been shown to lead to CouchDB hangs and -; failures on Erlang releases 21.0 - 21.3.8.12 and 22.0 -> 22.2.4. Do not -; enable when running with those versions. -;couch_server = false - -[cluster] -;q=2 -;n=3 -; placement = metro-dc-a:2,metro-dc-b:1 - -; Supply a comma-delimited list of node names that this node should -; contact in order to join a cluster. If a seedlist is configured the ``_up`` -; endpoint will return a 404 until the node has successfully contacted at -; least one of the members of the seedlist and replicated an up-to-date copy -; of the ``_nodes``, ``_dbs``, and ``_users`` system databases. -; seedlist = couchdb@node1.example.com,couchdb@node2.example.com - -[chttpd] -; These settings affect the main, clustered port (5984 by default). -port = {{cluster_port}} -bind_address = 127.0.0.1 -;backlog = 512 -;socket_options = [{sndbuf, 262144}, {nodelay, true}] -;server_options = [{recbuf, undefined}] -;require_valid_user = false -; require_valid_user_except_for_up = false -; List of headers that will be kept when the header Prefer: return=minimal is included in a request. -; If Server header is left out, Mochiweb will add its own one in. -;prefer_minimal = Cache-Control, Content-Length, Content-Range, Content-Type, ETag, Server, Transfer-Encoding, Vary -; -; Limit maximum number of databases when tying to get detailed information using -; _dbs_info in a request -;max_db_number_for_dbs_info_req = 100 - -; set to true to delay the start of a response until the end has been calculated -;buffer_response = false - -; authentication handlers -; authentication_handlers = {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler} -; uncomment the next line to enable proxy authentication -; authentication_handlers = {chttpd_auth, proxy_authentication_handler}, {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler} -; uncomment the next line to enable JWT authentication -; authentication_handlers = {chttpd_auth, jwt_authentication_handler}, {chttpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler} - -; prevent non-admins from accessing /_all_dbs -; admin_only_all_dbs = true - -; These options are moved from [httpd] -;secure_rewrites = true -;allow_jsonp = false - -;enable_cors = false -;enable_xframe_options = false - -; CouchDB can optionally enforce a maximum uri length; -;max_uri_length = 8000 - -;changes_timeout = 60000 -;config_whitelist = -;rewrite_limit = 100 -;x_forwarded_host = X-Forwarded-Host -;x_forwarded_proto = X-Forwarded-Proto -;x_forwarded_ssl = X-Forwarded-Ssl - -; Maximum allowed http request size. Applies to both clustered and local port. -;max_http_request_size = 4294967296 ; 4GB - -; Set to true to decode + to space in db and doc_id parts. -; decode_plus_to_space = true - -;[jwt_auth] -; List of claims to validate -; can be the name of a claim like "exp" or a tuple if the claim requires -; a parameter -; required_claims = exp, {iss, "IssuerNameHere"} -; roles_claim_name = https://example.com/roles -; -; [jwt_keys] -; Configure at least one key here if using the JWT auth handler. -; If your JWT tokens do not include a "kid" attribute, use "_default" -; as the config key, otherwise use the kid as the config key. -; Examples -; hmac:_default = aGVsbG8= -; hmac:foo = aGVsbG8= -; The config values can represent symmetric and asymmetrics keys. -; For symmetrics keys, the value is base64 encoded; -; hmac:_default = aGVsbG8= # base64-encoded form of "hello" -; For asymmetric keys, the value is the PEM encoding of the public -; key with newlines replaced with the escape sequence \n. -; rsa:foo = -----BEGIN PUBLIC KEY-----\nMIIBIjAN...IDAQAB\n-----END PUBLIC KEY-----\n -; ec:bar = -----BEGIN PUBLIC KEY-----\nMHYwEAYHK...AzztRs\n-----END PUBLIC KEY-----\n - -[couch_peruser] -; If enabled, couch_peruser ensures that a private per-user database -; exists for each document in _users. These databases are writable only -; by the corresponding user. Databases are in the following form: -; userdb-{hex encoded username} -;enable = false -; If set to true and a user is deleted, the respective database gets -; deleted as well. -;delete_dbs = false -; Set a default q value for peruser-created databases that is different from -; cluster / q -;q = 1 -; prefix for user databases. If you change this after user dbs have been -; created, the existing databases won't get deleted if the associated user -; gets deleted because of the then prefix mismatch. -;database_prefix = userdb- - -[httpd] -port = {{backend_port}} -bind_address = 127.0.0.1 -;authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler} - -; Options for the MochiWeb HTTP server. -;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] -; For more socket options, consult Erlang's module 'inet' man page. -;socket_options = [{recbuf, undefined}, {sndbuf, 262144}, {nodelay, true}] -;socket_options = [{sndbuf, 262144}] - -; These settings were moved to [chttpd] -; secure_rewrites, allow_jsonp, enable_cors, enable_xframe_options, -; max_uri_length, changes_timeout, config_whitelist, rewrite_limit, -; x_forwarded_host, x_forwarded_proto, x_forwarded_ssl, max_http_request_size - -; [httpd_design_handlers] -; _view = - -; [ioq] -; concurrency = 10 -; ratio = 0.01 - -[ssl] -;port = 6984 - -[chttpd_auth] -;authentication_db = _users - -; These options are moved from [couch_httpd_auth] -;authentication_redirect = /_utils/session.html -;require_valid_user = false -;timeout = 600 ; number of seconds before automatic logout -;auth_cache_size = 50 ; size is number of cache entries -;allow_persistent_cookies = true ; set to false to disallow persistent cookies -;iterations = 10 ; iterations for password hashing -;min_iterations = 1 -;max_iterations = 1000000000 -;password_scheme = pbkdf2 -; List of Erlang RegExp or tuples of RegExp and an optional error message. -; Where a new password must match all RegExp. -; Example: [{".{10,}", "Password min length is 10 characters."}, "\\d+"] -;password_regexp = [] -;proxy_use_secret = false -; comma-separated list of public fields, 404 if empty -;public_fields = -;secret = -;users_db_public = false -;cookie_domain = example.com -; Set the SameSite cookie property for the auth cookie. If empty, the SameSite property is not set. -;same_site = - -; [chttpd_auth_cache] -; max_lifetime = 600000 -; max_objects = -; max_size = 104857600 - -; [mem3] -; nodes_db = _nodes -; shard_cache_size = 25000 -; shards_db = _dbs -; sync_concurrency = 10 - -; [fabric] -; all_docs_concurrency = 10 -; changes_duration = -; shard_timeout_factor = 2 -; shard_timeout_min_msec = 100 -; uuid_prefix_len = 7 -; request_timeout = 60000 -; all_docs_timeout = 10000 -; attachments_timeout = 60000 -; view_timeout = 3600000 -; partition_view_timeout = 3600000 - -; [rexi] -; buffer_count = 2000 -; server_per_node = true -; stream_limit = 5 -; -; Use a single message to kill a group of remote workers. This feature is -; available starting with 3.0. When performing a rolling upgrade from 2.x to -; 3.x, set this value to false, then after all nodes were upgraded delete it so -; it can use the default true value. -;use_kill_all = true - -; [global_changes] -; max_event_delay = 25 -; max_write_delay = 500 -; update_db = true - -; [view_updater] -; min_writer_items = 100 -; min_writer_size = 16777216 - -[couch_httpd_auth] -; WARNING! This only affects the node-local port (5986 by default). -; You probably want the settings under [chttpd]. -authentication_db = _users - -; These settings were moved to [chttpd_auth] -; authentication_redirect, require_valid_user, timeout, -; auth_cache_size, allow_persistent_cookies, iterations, min_iterations, -; max_iterations, password_scheme, password_regexp, proxy_use_secret, -; public_fields, secret, users_db_public, cookie_domain, same_site - -; CSP (Content Security Policy) Support -[csp] -;utils_enable = true -;utils_header_value = default-src 'self'; img-src 'self'; font-src *; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; -;attachments_enable = true -;attachments_header_value = sandbox -;showlist_enable = true -;showlist_header_value = sandbox - -[cors] -;credentials = false -; List of origins separated by a comma, * means accept all -; Origins must include the scheme: http://example.com -; You can't set origins: * and credentials = true at the same time. -;origins = * -; List of accepted headers separated by a comma -; headers = -; List of accepted methods -; methods = - -; Configuration for a vhost -;[cors:http://example.com] -; credentials = false -; List of origins separated by a comma -; Origins must include the scheme: http://example.com -; You can't set origins: * and credentials = true at the same time. -;origins = -; List of accepted headers separated by a comma -; headers = -; List of accepted methods -; methods = - -; Configuration for the design document cache -;[ddoc_cache] -; The maximum size of the cache in bytes -;max_size = 104857600 ; 100MiB -; The period each cache entry should wait before -; automatically refreshing in milliseconds -;refresh_timeout = 67000 - -[x_frame_options] -; Settings same-origin will return X-Frame-Options: SAMEORIGIN. -; If same origin is set, it will ignore the hosts setting -; same_origin = true -; Settings hosts will return X-Frame-Options: ALLOW-FROM https://example.com/ -; List of hosts separated by a comma. * means accept all -; hosts = - -[native_query_servers] -; erlang query server -; enable_erlang_query_server = false - -; Changing reduce_limit to false will disable reduce_limit. -; If you think you're hitting reduce_limit with a "good" reduce function, -; please let us know on the mailing list so we can fine tune the heuristic. -[query_server_config] -; commit_freq = 5 -;reduce_limit = true -;os_process_limit = 100 -; os_process_idle_limit = 300 -; os_process_soft_limit = 100 -; Timeout for how long a response from a busy view group server can take. -; "infinity" is also a valid configuration value. -;group_info_timeout = 5000 -;query_limit = 268435456 -;partition_query_limit = 268435456 - -[mango] -; Set to true to disable the "index all fields" text index, which can lead -; to out of memory issues when users have documents with nested array fields. -;index_all_disabled = false -; Default limit value for mango _find queries. -;default_limit = 25 -; Ratio between documents scanned and results matched that will -; generate a warning in the _find response. Setting this to 0 disables -; the warning. -;index_scan_warning_threshold = 10 - -[indexers] -couch_mrview = true - -[feature_flags] -; This enables any database to be created as a partitioned databases (except system db's). -; Setting this to false will stop the creation of paritioned databases. -; paritioned||allowed* = true will scope the creation of partitioned databases -; to databases with 'allowed' prefix. -partitioned||* = true - -[uuids] -; Known algorithms: -; random - 128 bits of random awesome -; All awesome, all the time. -; sequential - monotonically increasing ids with random increments -; First 26 hex characters are random. Last 6 increment in -; random amounts until an overflow occurs. On overflow, the -; random prefix is regenerated and the process starts over. -; utc_random - Time since Jan 1, 1970 UTC with microseconds -; First 14 characters are the time in hex. Last 18 are random. -; utc_id - Time since Jan 1, 1970 UTC with microseconds, plus utc_id_suffix string -; First 14 characters are the time in hex. uuids/utc_id_suffix string value is appended to these. -;algorithm = sequential -; The utc_id_suffix value will be appended to uuids generated by the utc_id algorithm. -; Replicating instances should have unique utc_id_suffix values to ensure uniqueness of utc_id ids. -;utc_id_suffix = -# Maximum number of UUIDs retrievable from /_uuids in a single request -;max_count = 1000 - -[attachments] -;compression_level = 8 ; from 1 (lowest, fastest) to 9 (highest, slowest), 0 to disable compression -;compressible_types = text/*, application/javascript, application/json, application/xml - -[replicator] -; Random jitter applied on replication job startup (milliseconds) -;startup_jitter = 5000 -; Number of actively running replications -;max_jobs = 500 -;Scheduling interval in milliseconds. During each reschedule cycle -;interval = 60000 -; Maximum number of replications to start and stop during rescheduling. -;max_churn = 20 -; More worker processes can give higher network throughput but can also -; imply more disk and network IO. -;worker_processes = 4 -; With lower batch sizes checkpoints are done more frequently. Lower batch sizes -; also reduce the total amount of used RAM memory. -;worker_batch_size = 500 -; Maximum number of HTTP connections per replication. -;http_connections = 20 -; HTTP connection timeout per replication. -; Even for very fast/reliable networks it might need to be increased if a remote -; database is too busy. -;connection_timeout = 30000 -; Request timeout -;request_timeout = infinity -; If a request fails, the replicator will retry it up to N times. -;retries_per_request = 5 -; Use checkpoints -;use_checkpoints = true -; Checkpoint interval -;checkpoint_interval = 30000 -; Some socket options that might boost performance in some scenarios: -; {nodelay, boolean()} -; {sndbuf, integer()} -; {recbuf, integer()} -; {priority, integer()} -; See the `inet` Erlang module's man page for the full list of options. -;socket_options = [{keepalive, true}, {nodelay, false}] -; Path to a file containing the user's certificate. -;cert_file = /full/path/to/server_cert.pem -; Path to file containing user's private PEM encoded key. -;key_file = /full/path/to/server_key.pem -; String containing the user's password. Only used if the private keyfile is password protected. -;password = somepassword -; Set to true to validate peer certificates. -;verify_ssl_certificates = false -; File containing a list of peer trusted certificates (in the PEM format). -;ssl_trusted_certificates_file = /etc/ssl/certs/ca-certificates.crt -; Maximum peer certificate depth (must be set even if certificate validation is off). -;ssl_certificate_max_depth = 3 -; Maximum document ID length for replication. -;max_document_id_length = infinity -; How much time to wait before retrying after a missing doc exception. This -; exception happens if the document was seen in the changes feed, but internal -; replication hasn't caught up yet, and fetching document's revisions -; fails. This a common scenario when source is updated while continous -; replication is running. The retry period would depend on how quickly internal -; replication is expected to catch up. In general this is an optimisation to -; avoid crashing the whole replication job, which would consume more resources -; and add log noise. -;missing_doc_retry_msec = 2000 -; Wait this many seconds after startup before attaching changes listeners -; cluster_start_period = 5 -; Re-check cluster state at least every cluster_quiet_period seconds -; cluster_quiet_period = 60 - -; List of replicator client authentication plugins to try. Plugins will be -; tried in order. The first to initialize successfully will be used for that -; particular endpoint (source or target). Normally couch_replicator_auth_noop -; would be used at the end of the list as a "catch-all". It doesn't do anything -; and effectively implements the previous behavior of using basic auth. -; There are currently two plugins available: -; couch_replicator_auth_session - use _session cookie authentication -; couch_replicator_auth_noop - use basic authentication (previous default) -; Currently, the new _session cookie authentication is tried first, before -; falling back to the old basic authenticaion default: -;auth_plugins = couch_replicator_auth_session,couch_replicator_auth_noop -; To restore the old behaviour, use the following value: -;auth_plugins = couch_replicator_auth_noop - -; Force couch_replicator_auth_session plugin to refresh the session -; periodically if max-age is not present in the cookie. This is mostly to -; handle the case where anonymous writes are allowed to the database and a VDU -; function is used to forbid writes based on the authenticated user name. In -; that case this value should be adjusted based on the expected minimum session -; expiry timeout on replication endpoints. If session expiry results in a 401 -; or 403 response this setting is not needed. -;session_refresh_interval_sec = 550 - -; Usage coefficient decays historic fair share usage every scheduling -; cycle. The value must be between 0.0 and 1.0. Lower values will -; ensure historic usage decays quicker and higher values means it will -; be remembered longer. -;usage_coeff = 0.5 - -; Priority coefficient decays all the job priorities such that they slowly -; drift towards the front of the run queue. This coefficient defines a maximum -; time window over which this algorithm would operate. For example, if this -; value is too small (0.1), after a few cycles quite a few jobs would end up at -; priority 0, and would render this algorithm useless. The default value of -; 0.98 is picked such that if a job ran for one scheduler cycle, then didn't -; get to run for 7 hours, it would still have priority > 0. 7 hours was picked -; as it was close enought to 8 hours which is the default maximum error backoff -; interval. -;priority_coeff = 0.98 - - -[replicator.shares] -; Fair share configuration section. More shares result in a higher -; chance that jobs from that db get to run. The default value is 100, -; minimum is 1 and maximum is 1000. The configuration may be set even -; if the database does not exist. -;_replicator = 100 - - -[log] -; Possible log levels: -; debug -; info -; notice -; warning, warn -; error, err -; critical, crit -; alert -; emergency, emerg -; none -; -;level = info -; -; Set the maximum log message length in bytes that will be -; passed through the writer -; -; max_message_size = 16000 -; -; Do not log last message received by terminated process -; strip_last_msg = true -; -; List of fields to remove before logging the crash report -; filter_fields = [pid, registered_name, error_info, messages] -; -; There are four different log writers that can be configured -; to write log messages. The default writes to stderr of the -; Erlang VM which is useful for debugging/development as well -; as a lot of container deployments. -; -; There's also a file writer that works with logrotate, a -; rsyslog writer for deployments that need to have logs sent -; over the network, and a journald writer that's more suitable -; when using systemd journald. -; -;writer = stderr -; Journald Writer notes: -; -; The journald writer doesn't have any options. It still writes -; the logs to stderr, but without the timestamp prepended, since -; the journal will add it automatically, and with the log level -; formated as per -; https://www.freedesktop.org/software/systemd/man/sd-daemon.html -; -; -; File Writer Options: -; -; The file writer will check every 30s to see if it needs -; to reopen its file. This is useful for people that configure -; logrotate to move log files periodically. -; -; file = ./couch.log ; Path name to write logs to -; -; Write operations will happen either every write_buffer bytes -; or write_delay milliseconds. These are passed directly to the -; Erlang file module with the write_delay option documented here: -; -; http://erlang.org/doc/man/file.html -; -; write_buffer = 0 -; write_delay = 0 -; -; -; Syslog Writer Options: -; -; The syslog writer options all correspond to their obvious -; counter parts in rsyslog nomenclature. -; -; syslog_host = -; syslog_port = 514 -; syslog_appid = couchdb -; syslog_facility = local2 - -[stats] -; Stats collection interval in seconds. Default 10 seconds. -;interval = 10 - -[smoosh] -; -; More documentation on these is in the Automatic Compaction -; section of the documentation. -; -;db_channels = upgrade_dbs,ratio_dbs,slack_dbs -;view_channels = upgrade_views,ratio_views,slack_views -; -;[smoosh.ratio_dbs] -;priority = ratio -;min_priority = 2.0 -; -;[smoosh.ratio_views] -;priority = ratio -;min_priority = 2.0 -; -;[smoosh.slack_dbs] -;priority = slack -;min_priority = 536870912 -; -;[smoosh.slack_views] -;priority = slack -;min_priority = 536870912 -; -; Directory to store the state of smoosh -state_dir = {{state_dir}} - -; Sets the log level for informational compaction related entries. -;compaction_log_level = debug - -[ioq] -; The maximum number of concurrent in-flight IO requests that -;concurrency = 10 - -; The fraction of the time that a background IO request will be selected -; over an interactive IO request when both queues are non-empty -;ratio = 0.01 - -[ioq.bypass] -; System administrators can choose to submit specific classes of IO directly -; to the underlying file descriptor or OS process, bypassing the queues -; altogether. Installing a bypass can yield higher throughput and lower -; latency, but relinquishes some control over prioritization. The following -; classes are recognized with the following defaults: - -; Messages on their way to an external process (e.g., couchjs) are bypassed -;os_process = true - -; Disk IO fulfilling interactive read requests is bypassed -;read = true - -; Disk IO required to update a database is bypassed -;write = true - -; Disk IO required to update views and other secondary indexes is bypassed -;view_update = true - -; Disk IO issued by the background replication processes that fix any -; inconsistencies between shard copies is queued -;shard_sync = false - -; Disk IO issued by compaction jobs is queued -;compaction = false - -[dreyfus] -; The name and location of the Clouseau Java service required to -; enable Search functionality. -; name = clouseau@127.0.0.1 - -; CouchDB will try to re-connect to Clouseau using a bounded -; exponential backoff with the following number of iterations. -; retry_limit = 5 - -; The default number of results returned from a global search query. -; limit = 25 - -; The default number of results returned from a search on a partition -; of a database. -; limit_partitions = 2000 - -; The maximum number of results that can be returned from a global -; search query (or any search query on a database without user-defined -; partitions). Attempts to set ?limit=N higher than this value will -; be rejected. -; max_limit = 200 - -; The maximum number of results that can be returned when searching -; a partition of a database. Attempts to set ?limit=N higher than this -; value will be rejected. If this config setting is not defined, -; CouchDB will use the value of `max_limit` instead. If neither is -; defined, the default is 2000 as stated here. -; max_limit_partitions = 2000 - -[reshard] -;max_jobs = 48 -;max_history = 20 -;max_retries = 5 -;retry_interval_sec = 10 -;delete_source = true -;update_shard_map_timeout_sec = 60 -;source_close_timeout_sec = 600 -;require_node_param = false -;require_range_param = false - -; How many times to retry building an individual index -;index_max_retries = 5 - -; How many seconds to wait between retries for an individual index -;index_retry_interval_sec = 10 - -[prometheus] -additional_port = false -bind_address = 127.0.0.1 -port = {{prometheus_port}} - -[view_upgrade] -; When enabled, views with more than one collator versions will be submitted -; for auto-compaction to smoosh's "upgrade_views" channel. -;compact_on_collator_upgrade = true - -; Eagerly commit views which been upgraded from older header formats. A reason -; to disable this setting could be if the views need an upgrade but located on -; read-only file system. -;commit_on_header_upgrade = true diff --git a/rel/overlay/etc/local.d/README b/rel/overlay/etc/local.d/README deleted file mode 100644 index 5cc9ed123..000000000 --- a/rel/overlay/etc/local.d/README +++ /dev/null @@ -1,8 +0,0 @@ -CouchDB local configuration files - -Files found under the etc/local.d directory that end with .ini are parsed -within couchdb(1) at startup. - -This directory is intended for system administrator overrides of CouchDB -defaults. Package maintainers should be placing overrides in the -etc/default.d directory instead. diff --git a/rel/overlay/etc/local.ini b/rel/overlay/etc/local.ini deleted file mode 100644 index 398cf3e2c..000000000 --- a/rel/overlay/etc/local.ini +++ /dev/null @@ -1,95 +0,0 @@ -; CouchDB Configuration Settings - -; Custom settings should be made in this file. They will override settings -; in default.ini, but unlike changes made to default.ini, this file won't be -; overwritten on server upgrade. - -[couchdb] -;max_document_size = 4294967296 ; bytes -;os_process_timeout = 5000 - -[couch_peruser] -; If enabled, couch_peruser ensures that a private per-user database -; exists for each document in _users. These databases are writable only -; by the corresponding user. Databases are in the following form: -; userdb-{hex encoded username} -;enable = true -; If set to true and a user is deleted, the respective database gets -; deleted as well. -;delete_dbs = true -; Set a default q value for peruser-created databases that is different from -; cluster / q -;q = 1 - -[chttpd] -;port = 5984 -;bind_address = 127.0.0.1 -; Options for the MochiWeb HTTP server. -;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] -; For more socket options, consult Erlang's module 'inet' man page. -;socket_options = [{sndbuf, 262144}, {nodelay, true}] - -[httpd] -; NOTE that this only configures the "backend" node-local port, not the -; "frontend" clustered port. You probably don't want to change anything in -; this section. -; Uncomment next line to trigger basic-auth popup on unauthorized requests. -;WWW-Authenticate = Basic realm="administrator" - -; Uncomment next line to set the configuration modification whitelist. Only -; whitelisted values may be changed via the /_config URLs. To allow the admin -; to change this value over HTTP, remember to include {httpd,config_whitelist} -; itself. Excluding it from the list would require editing this file to update -; the whitelist. -;config_whitelist = [{httpd,config_whitelist}, {log,level}, {etc,etc}] - -[chttpd_auth] -; If you set this to true, you should also uncomment the WWW-Authenticate line -; above. If you don't configure a WWW-Authenticate header, CouchDB will send -; Basic realm="server" in order to prevent you getting logged out. -; require_valid_user = false - -[ssl] -;enable = true -;cert_file = /full/path/to/server_cert.pem -;key_file = /full/path/to/server_key.pem -;password = somepassword -; set to true to validate peer certificates -;verify_ssl_certificates = false -; Set to true to fail if the client does not send a certificate. Only used if verify_ssl_certificates is true. -;fail_if_no_peer_cert = false -; Path to file containing PEM encoded CA certificates (trusted -; certificates used for verifying a peer certificate). May be omitted if -; you do not want to verify the peer. -;cacert_file = /full/path/to/cacertf -; The verification fun (optional) if not specified, the default -; verification fun will be used. -;verify_fun = {Module, VerifyFun} -; maximum peer certificate depth -;ssl_certificate_max_depth = 1 -; -; Reject renegotiations that do not live up to RFC 5746. -;secure_renegotiate = true -; The cipher suites that should be supported. -; Can be specified in erlang format "{ecdhe_ecdsa,aes_128_cbc,sha256}" -; or in OpenSSL format "ECDHE-ECDSA-AES128-SHA256". -;ciphers = ["ECDHE-ECDSA-AES128-SHA256", "ECDHE-ECDSA-AES128-SHA"] -; The SSL/TLS versions to support -;tls_versions = [tlsv1, 'tlsv1.1', 'tlsv1.2'] - -; To enable Virtual Hosts in CouchDB, add a vhost = path directive. All requests to -; the Virual Host will be redirected to the path. In the example below all requests -; to http://example.com/ are redirected to /database. -; If you run CouchDB on a specific port, include the port number in the vhost: -; example.com:5984 = /database -[vhosts] -;example.com = /database/ - -; To create an admin account uncomment the '[admins]' section below and add a -; line in the format 'username = password'. When you next start CouchDB, it -; will change the password to a hash (so that your passwords don't linger -; around in plain-text files). You can add more admin accounts with more -; 'username = password' lines. Don't forget to restart CouchDB after -; changing this. -[admins] -;admin = mysecretpassword diff --git a/rel/overlay/etc/vm.args b/rel/overlay/etc/vm.args deleted file mode 100644 index 3ade5cbe5..000000000 --- a/rel/overlay/etc/vm.args +++ /dev/null @@ -1,97 +0,0 @@ -# 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. - -# Each node in the system must have a unique name. These are specified through -# the Erlang -name flag, which takes the form: -# -# -name nodename@ -# -# or -# -# -name nodename@ -# -# CouchDB recommends the following values for this flag: -# -# 1. If this is a single node, not in a cluster, use: -# -name couchdb@127.0.0.1 -# -# 2. If DNS is configured for this host, use the FQDN, such as: -# -name couchdb@my.host.domain.com -# -# 3. If DNS isn't configured for this host, use IP addresses only, such as: -# -name couchdb@192.168.0.1 -# -# Do not rely on tricks with /etc/hosts or libresolv to handle anything -# other than the above 3 approaches correctly. They will not work reliably. -# -# Multiple CouchDBs running on the same machine can use couchdb1@, couchdb2@, -# etc. -{{node_name}} - -# All nodes must share the same magic cookie for distributed Erlang to work. -# Uncomment the following line and append a securely generated random value. -# -setcookie - -# Which interfaces should the node listen on? --kernel inet_dist_use_interface {127,0,0,1} - -# Tell kernel and SASL not to log anything --kernel error_logger silent --sasl sasl_error_logger false - -# Use kernel poll functionality if supported by emulator -+K true - -# Start a pool of asynchronous IO threads -+A 16 - -# Comment this line out to enable the interactive Erlang shell on startup -+Bd -noinput - -# Force use of the smp scheduler, fixes #1296 --smp enable - -# Set maximum SSL session lifetime to reap terminated replication readers --ssl session_lifetime 300 - -## TLS Distribution -## Use TLS for connections between Erlang cluster members. -## http://erlang.org/doc/apps/ssl/ssl_distribution.html -## -## Generate Cert(PEM) File -## This is just an example command to generate a certfile (PEM). -## This is not an endorsement of specific expiration limits, key sizes, or algorithms. -## $ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -## $ cat key.pem cert.pem > dev/erlserver.pem && rm key.pem cert.pem -## -## Generate a Config File (couch_ssl_dist.conf) -## [{server, -## [{certfile, ""}, -## {secure_renegotiate, true}]}, -## {client, -## [{secure_renegotiate, true}]}]. -## -## CouchDB recommends the following values for no_tls flag: -## 1. Use TCP only, set to true, such as: -## -couch_dist no_tls true -## 2. Use TLS only, set to false, such as: -## -couch_dist no_tls false -## 3. Specify which node to use TCP, such as: -## -couch_dist no_tls \"*@127.0.0.1\" -## -## To ensure search works, make sure to set 'no_tls' option for the clouseau node. -## By default that would be "clouseau@127.0.0.1". -## Don't forget to override the paths to point to your certificate(s) and key(s)! -## -#-proto_dist couch -#-couch_dist no_tls '"clouseau@127.0.0.1"' -#-ssl_dist_optfile diff --git a/rel/plugins/eunit_plugin.erl b/rel/plugins/eunit_plugin.erl deleted file mode 100644 index 8f298db5f..000000000 --- a/rel/plugins/eunit_plugin.erl +++ /dev/null @@ -1,59 +0,0 @@ -% 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. - --module(eunit_plugin). - --export([setup_eunit/2]). - -setup_eunit(Config, AppFile) -> - case is_base_dir(Config) of - false -> ok; - true -> build_eunit_config(Config, AppFile) - end. - -%% from https://github.com/ChicagoBoss/ChicagoBoss/blob/master/skel/priv/rebar/boss_plugin.erl -is_base_dir(RebarConf) -> - filename:absname(rebar_utils:get_cwd()) =:= - rebar_config:get_xconf(RebarConf, base_dir, undefined). - -build_eunit_config(Config0, AppFile) -> - Cwd = filename:absname(rebar_utils:get_cwd()), - DataDir = Cwd ++ "/tmp/data", - ViewIndexDir = Cwd ++ "/tmp/data", - StateDir = Cwd ++ "/tmp/data", - TmpDataDir = Cwd ++ "/tmp/tmp_data", - cleanup_dirs([DataDir, TmpDataDir]), - Config1 = rebar_config:set_global(Config0, template, "setup_eunit"), - Config2 = rebar_config:set_global(Config1, prefix, Cwd), - Config3 = rebar_config:set_global(Config2, data_dir, DataDir), - Config4 = rebar_config:set_global(Config3, view_index_dir, ViewIndexDir), - Config = rebar_config:set_global(Config4, state_dir, StateDir), - rebar_templater:create(Config, AppFile). - -cleanup_dirs(Dirs) -> - lists:foreach( - fun(Dir) -> - case filelib:is_dir(Dir) of - true -> del_dir(Dir); - false -> ok - end - end, - Dirs - ). - -del_dir(Dir) -> - All = filelib:wildcard(Dir ++ "/**"), - {Dirs, Files} = lists:partition(fun filelib:is_dir/1, All), - ok = lists:foreach(fun file:delete/1, Files), - SortedDirs = lists:sort(fun(A, B) -> length(A) > length(B) end, Dirs), - ok = lists:foreach(fun file:del_dir/1, SortedDirs), - ok = file:del_dir(Dir). diff --git a/rel/reltool.config b/rel/reltool.config deleted file mode 100644 index ab26fb2ed..000000000 --- a/rel/reltool.config +++ /dev/null @@ -1,152 +0,0 @@ -% 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. - -{sys, [ - {lib_dirs, ["../src"]}, - {rel, "couchdb", "3.2.2", [ - %% stdlib - asn1, - compiler, - crypto, - inets, - kernel, - runtime_tools, - sasl, - ssl, - stdlib, - syntax_tools, - xmerl, - %% couchdb - b64url, - bear, - chttpd, - config, - couch, - couch_epi, - couch_index, - couch_log, - couch_mrview, - couch_plugins, - couch_replicator, - couch_stats, - couch_event, - couch_peruser, - couch_dist, - custodian, - ddoc_cache, - dreyfus, - ets_lru, - fabric, - folsom, - global_changes, - hyper, - ibrowse, - ioq, - jiffy, - jwtf, - ken, - khash, - mango, - mem3, - mochiweb, - rexi, - setup, - smoosh, - snappy, - weatherreport, - couch_prometheus, - - %% extra - recon - ]}, - {rel, "start_clean", "", [kernel, stdlib]}, - {boot_rel, "couchdb"}, - {profile, embedded}, - {excl_sys_filters, ["^bin/.*", "^erts.*/bin/(dialyzer|typer)"]}, - {excl_archive_filters, [".*"]}, - {incl_cond, exclude}, - - %% stdlib - {app, asn1, [{incl_cond, include}]}, - {app, compiler, [{incl_cond, include}]}, - {app, crypto, [{incl_cond, include}]}, - {app, inets, [{incl_cond, include}]}, - {app, kernel, [{incl_cond, include}]}, - {app, public_key, [{incl_cond, include}]}, - {app, runtime_tools, [{incl_cond, include}]}, - {app, sasl, [{incl_cond, include}]}, - {app, ssl, [{incl_cond, include}]}, - {app, stdlib, [{incl_cond, include}]}, - {app, syntax_tools, [{incl_cond, include}]}, - {app, xmerl, [{incl_cond, include}]}, - - %% couchdb - {app, b64url, [{incl_cond, include}]}, - {app, bear, [{incl_cond, include}]}, - {app, chttpd, [{incl_cond, include}]}, - {app, config, [{incl_cond, include}]}, - {app, couch, [{incl_cond, include}]}, - {app, couch_epi, [{incl_cond, include}]}, - {app, couch_index, [{incl_cond, include}]}, - {app, couch_log, [{incl_cond, include}]}, - {app, couch_mrview, [{incl_cond, include}]}, - {app, couch_plugins, [{incl_cond, include}]}, - {app, couch_replicator, [{incl_cond, include}]}, - {app, couch_stats, [{incl_cond, include}]}, - {app, couch_event, [{incl_cond, include}]}, - {app, couch_peruser, [{incl_cond, include}]}, - {app, couch_dist ,[{incl_cond, include}]}, - {app, custodian, [{incl_cond, include}]}, - {app, ddoc_cache, [{incl_cond, include}]}, - {app, dreyfus, [{incl_cond, include}]}, - {app, ets_lru, [{incl_cond, include}]}, - {app, fabric, [{incl_cond, include}]}, - {app, folsom, [{incl_cond, include}]}, - {app, global_changes, [{incl_cond, include}]}, - {app, hyper, [{incl_cond, include}]}, - {app, ibrowse, [{incl_cond, include}]}, - {app, ioq, [{incl_cond, include}]}, - {app, jiffy, [{incl_cond, include}]}, - {app, jwtf, [{incl_cond, include}]}, - {app, ken, [{incl_cond, include}]}, - {app, khash, [{incl_cond, include}]}, - {app, mango, [{incl_cond, include}]}, - {app, mem3, [{incl_cond, include}]}, - {app, mochiweb, [{incl_cond, include}]}, - {app, rexi, [{incl_cond, include}]}, - {app, setup, [{incl_cond, include}]}, - {app, smoosh, [{incl_cond, include}]}, - {app, snappy, [{incl_cond, include}]}, - {app, weatherreport, [{incl_cond, include}]}, - {app, couch_prometheus, [{incl_cond, include}]}, - - %% extra - {app, recon, [{incl_cond, include}]} -]}. - -{overlay_vars, "couchdb.config"}. -{overlay, [ - {copy, "../LICENSE", "LICENSE"}, - {mkdir, "var/log"}, - {copy, "overlay/bin"}, - {copy, "overlay/etc"}, - {copy, "../src/couch/priv/couchjs", "bin/couchjs"}, - {copy, "../share/server/main.js", "share/server/main.js"}, - {copy, "../share/server/main-coffee.js", "share/server/main-coffee.js"}, - {copy, "../src/weatherreport/weatherreport", "bin/weatherreport"}, - {copy, "files/sys.config", "releases/\{\{rel_vsn\}\}/sys.config"}, - {copy, "files/vm.args", "releases/\{\{rel_vsn\}\}/vm.args"}, - {template, "overlay/etc/default.ini", "etc/default.ini"}, - {template, "overlay/etc/vm.args", "etc/vm.args"}, - {template, "files/couchdb.in", "bin/couchdb"}, - {template, "files/couchdb.cmd.in", "bin/couchdb.cmd"} -]}. diff --git a/setup_eunit.template b/setup_eunit.template deleted file mode 100644 index ceef60d12..000000000 --- a/setup_eunit.template +++ /dev/null @@ -1,20 +0,0 @@ -{variables, [ - {package_author_name, "The Apache Software Foundation"}, - {cluster_port, 5984}, - {backend_port, 5986}, - {prometheus_port, 17986}, - {node_name, "-name couchdbtest@127.0.0.1"}, - - {data_dir, "/tmp"}, - {prefix, "/tmp"}, - {view_index_dir, "/tmp"}, - {state_dir, "/tmp"} -]}. -{dir, "tmp"}. -{dir, "tmp/etc"}. -{dir, "tmp/data"}. -{dir, "tmp/tmp_data"}. -{template, "rel/overlay/etc/default.ini", "tmp/etc/default_eunit.ini"}. -{template, "rel/overlay/etc/local.ini", "tmp/etc/local_eunit.ini"}. -{template, "rel/files/eunit.ini", "tmp/etc/eunit.ini"}. -{template, "rel/overlay/etc/vm.args", "tmp/etc/vm.args"}. diff --git a/share/server/60/escodegen.js b/share/server/60/escodegen.js deleted file mode 100644 index 747a7322c..000000000 --- a/share/server/60/escodegen.js +++ /dev/null @@ -1 +0,0 @@ -(function(b){function a(b,d){if({}.hasOwnProperty.call(a.cache,b))return a.cache[b];var e=a.resolve(b);if(!e)throw new Error('Failed to resolve module '+b);var c={id:b,require:a,filename:b,exports:{},loaded:!1,parent:d,children:[]};d&&d.children.push(c);var f=b.slice(0,b.lastIndexOf('/')+1);return a.cache[b]=c.exports,e.call(c.exports,c,c.exports,f,b),c.loaded=!0,a.cache[b]=c.exports}a.modules={},a.cache={},a.resolve=function(b){return{}.hasOwnProperty.call(a.modules,b)?a.modules[b]:void 0},a.define=function(b,c){a.modules[b]=c};var c=function(a){return a='/',{title:'browser',version:'v6.8.0',browser:!0,env:{},argv:[],nextTick:b.setImmediate||function(a){setTimeout(a,0)},cwd:function(){return a},chdir:function(b){a=b}}}();a.define('/tools/entry-point.js',function(c,d,e,f){!function(){'use strict';b.escodegen=a('/escodegen.js',c),escodegen.browser=!0}()}),a.define('/escodegen.js',function(d,c,e,f){!function(k,e,af,N,_,m,J,n,F,A,Z,ae,S,ad,i,f,W,ac,L,aa,t,Y,B,C,x,a9,a7,w,E,G,V,Q,q,U,P,g,R,a6,X,l,y,K,a5,a4){'use strict';function ap(a){return o.Expression.hasOwnProperty(a.type)}function a3(a){return o.Statement.hasOwnProperty(a.type)}function a2(){return{indent:null,base:null,parse:null,comment:!1,format:{indent:{style:' ',base:0,adjustMultilineComment:!1},newline:'\n',space:' ',json:!1,renumber:!1,hexadecimal:!1,quotes:'single',escapeless:!1,compact:!1,parentheses:!0,semicolons:!0,safeConcatenation:!1,preserveBlankLines:!1},moz:{comprehensionExpressionStartsWithAssignment:!1,starlessGenerator:!1},sourceMap:null,sourceMapRoot:null,sourceMapWithCode:!1,directive:!1,raw:!0,verbatim:null,sourceCode:null}}function H(b,a){var c='';for(a|=0;a>0;a>>>=1,b+=b)a&1&&(c+=b);return c}function am(a){return/[\r\n]/g.test(a)}function r(b){var a=b.length;return a&&m.code.isLineTerminator(b.charCodeAt(a-1))}function a0(c,b){var a;for(a in b)b.hasOwnProperty(a)&&(c[a]=b[a]);return c}function T(b,d){function e(a){return typeof a==='object'&&a instanceof Object&&!(a instanceof RegExp)}var a,c;for(a in d)d.hasOwnProperty(a)&&(c=d[a],e(c)?e(b[a])?T(b[a],c):b[a]=T({},c):b[a]=c);return b}function ao(c){var b,e,a,f,d;if(c!==c)throw new Error('Numeric literal whose value is NaN');if(c<0||c===0&&1/c<0)throw new Error('Numeric literal whose value is negative');if(c===1/0)return A?'null':Z?'1e400':'1e+400';if(b=''+c,!Z||b.length<3)return b;e=b.indexOf('.'),!A&&b.charCodeAt(0)===48&&e===1&&(e=0,b=b.slice(1)),a=b,b=b.replace('e+','e'),f=0,(d=a.indexOf('e'))>0&&(f=+a.slice(d+1),a=a.slice(0,d)),e>=0&&(f-=a.length-e-1,a=+(a.slice(0,e)+a.slice(e+1))+''),d=0;while(a.charCodeAt(a.length+d-1)===48)--d;return d!==0&&(f-=d,a=a.slice(0,d)),f!==0&&(a+='e'+f),(a.length1e12&&Math.floor(c)===c&&(a='0x'+c.toString(16)).length255?'\\u'+'0000'.slice(b.length)+b:a===0&&!m.code.isDecimalDigit(c)?'\\0':a===11?'\\x0B':'\\x'+'00'.slice(b.length)+b)}function ai(a){if(a===92)return'\\\\';if(a===10)return'\\n';if(a===13)return'\\r';if(a===8232)return'\\u2028';if(a===8233)return'\\u2029';throw new Error('Incorrectly classified character')}function aj(d){var a,e,c,b;for(b=S==='double'?'"':"'",a=0,e=d.length;a126))){b+=ar(a,d.charCodeAt(c+1));continue}b+=String.fromCharCode(a)}if(e=!(S==='double'||S==='auto'&&i=0;--a)if(m.code.isLineTerminator(b.charCodeAt(a)))break;return b.length-1-a}function ah(k,i){var b,a,e,g,d,c,f,h;for(b=k.split(/\r\n|[\r\n]/),c=Number.MAX_VALUE,a=1,e=b.length;ad&&(c=d)}for(i!==void 0?(f=n,b[1][c]==='*'&&(i+=' '),n=i):(c&1&&--c,f=n),a=1,e=b.length;a0){if(q=a,x){for(b=d.leadingComments[0],a=[],i=b.extendedRange,f=b.range,h=C.substring(i[0],f[0]),e=(h.match(/\n/g)||[]).length,e>0?(a.push(H('\n',e)),a.push(u(D(b)))):(a.push(h),a.push(D(b))),o=f,c=1,g=d.leadingComments.length;c0?(a.push(H('\n',e)),a.push(u(D(b)))):(a.push(h),a.push(D(b)));else for(p=!r(j(a).toString()),m=H(' ',as(j([n,a,F]).toString())),c=0,g=d.trailingComments.length;c':e.Relational,'<=':e.Relational,'>=':e.Relational,'in':e.Relational,'instanceof':e.Relational,'<<':e.BitwiseSHIFT,'>>':e.BitwiseSHIFT,'>>>':e.BitwiseSHIFT,'+':e.Additive,'-':e.Additive,'*':e.Multiplicative,'%':e.Multiplicative,'/':e.Multiplicative},w=1,E=2,G=4,V=8,Q=16,q=32,U=E|G,P=w|E,g=w|E|G,R=w,a6=G,X=w|G,l=w,y=w|q,K=0,a5=w|Q,a4=w|V,J=Array.isArray,J||(J=function a(b){return Object.prototype.toString.call(b)==='[object Array]'}),o.prototype.maybeBlock=function(a,c){var d,b,e=this;return b=!t.comment||!a.leadingComments,a.type===k.BlockStatement&&b?[f,this.generateStatement(a,c)]:a.type===k.EmptyStatement&&b?';':(p(function(){d=[i,u(e.generateStatement(a,c))]}),d)},o.prototype.maybeBlockSuffix=function(c,a){var b=r(j(a).toString());return c.type===k.BlockStatement&&!(t.comment&&c.leadingComments)&&!b?[a,f]:b?[a,n]:[a,i,n]},o.prototype.generatePattern=function(a,b,c){return a.type===k.Identifier?z(a):this.generateExpression(a,b,c)},o.prototype.generateFunctionParams=function(a){var c,d,b,h;if(h=!1,a.type===k.ArrowFunctionExpression&&!a.rest&&(!a.defaults||a.defaults.length===0)&&a.params.length===1&&a.params[0].type===k.Identifier)b=[M(a,!0),z(a.params[0])];else{for(b=a.type===k.ArrowFunctionExpression?[M(a,!1)]:[],b.push('('),a.defaults&&(h=!0),c=0,d=a.params.length;c')),b.expression?(a.push(f),c=this.generateExpression(b.body,e.Assignment,g),c.toString().charAt(0)==='{'&&(c=['(',c,')']),a.push(c)):a.push(this.maybeBlock(b.body,a4)),a},o.prototype.generateIterationForStatement=function(d,b,i){var a=['for'+f+'('],c=this;return p(function(){b.left.type===k.VariableDeclaration?p(function(){a.push(b.left.kind+v()),a.push(c.generateStatement(b.left.declarations[0],K))}):a.push(c.generateExpression(b.left,e.Call,g)),a=h(a,d),a=[h(a,c.generateExpression(b.right,e.Sequence,g)),')']}),a.push(this.maybeBlock(b.body,i)),a},o.prototype.generatePropertyKey=function(d,b,c){var a=[];return b&&a.push('['),c.type==='AssignmentPattern'?a.push(this.AssignmentPattern(c,e.Sequence,g)):a.push(this.generateExpression(d,e.Sequence,g)),b&&a.push(']'),a},o.prototype.generateAssignment=function(c,d,g,b,a){return e.Assignment2)&&(d=C.substring(c[0]+1,c[1]-1),d[0]==='\n'&&(b=['{']),b.push(d));var g,h,m,k;for(k=l,f&V&&(k|=Q),g=0,h=a.body.length;g0&&!(a.body[g-1].trailingComments||a.body[g].leadingComments)&&I(a.body[g-1].range[1],a.body[g].range[0],b)),g===h-1&&(k|=q),a.body[g].leadingComments&&x?m=e.generateStatement(a.body[g],k):m=u(e.generateStatement(a.body[g],k)),b.push(m),r(j(m).toString())||(x&&g1?p(j):j(),a.push(this.semicolon(h)),a},ThrowStatement:function(a,b){return[h('throw',this.generateExpression(a.argument,e.Sequence,g)),this.semicolon(b)]},TryStatement:function(b,f){var a,c,d,e;if(a=['try',this.maybeBlock(b.block,l)],a=this.maybeBlockSuffix(b.block,a),b.handlers)for(c=0,d=b.handlers.length;c0?'\n':''],f=a5,a=0;a0&&!(b.body[a-1].trailingComments||b.body[a].leadingComments)&&I(b.body[a-1].range[1],b.body[a].range[0],c)),e=u(this.generateStatement(b.body[a],f)),c.push(e),a+10){for(a.push('('),b=0,i=c;b=2&&b.charCodeAt(0)===48)&&a.push('.')),a.push('.'),a.push(z(c.property))),s(a,e.Member,f)},MetaProperty:function(b,c,d){var a;return a=[],a.push(b.meta),a.push('.'),a.push(b.property),s(a,e.Member,c)},UnaryExpression:function(d,l,n){var a,b,i,k,c;return b=this.generateExpression(d.argument,e.Unary,g),f===''?a=h(d.operator,b):(a=[d.operator],d.operator.length>2?a=h(a,b):(k=j(a).toString(),c=k.charCodeAt(k.length-1),i=b.toString().charCodeAt(0),(c===43||c===45)&&c===i||m.code.isIdentifierPartES5(c)&&m.code.isIdentifierPartES5(i)?(a.push(v()),a.push(b)):a.push(b))),s(a,e.Unary,l)},YieldExpression:function(b,c,d){var a;return b.delegate?a='yield*':a='yield',b.argument&&(a=h(a,this.generateExpression(b.argument,e.Yield,g))),s(a,e.Yield,c)},AwaitExpression:function(a,c,d){var b=h(a.all?'await*':'await',this.generateExpression(a.argument,e.Await,g));return s(b,e.Await,c)},UpdateExpression:function(a,b,c){return a.prefix?s([a.operator,this.generateExpression(a.argument,e.Unary,g)],e.Unary,b):s([this.generateExpression(a.argument,e.Postfix,g),a.operator],e.Postfix,b)},FunctionExpression:function(a,c,d){var b=[M(a,!0),'function'];return a.id?(b.push(O(a)||v()),b.push(z(a.id))):b.push(O(a)||f),b.push(this.generateFunctionBody(a)),b},ArrayPattern:function(a,b,c){return this.ArrayExpression(a,b,c,!0)},ArrayExpression:function(c,k,l,h){var a,b,d=this;return c.elements.length?(b=h?!1:c.elements.length>1,a=['[',b?i:''],p(function(k){var h,j;for(h=0,j=c.elements.length;h1,p(function(){c=h.generateExpression(b.properties[0],e.Sequence,g)}),d||am(j(c).toString())?(p(function(k){var f,j;if(a=['{',i,k,c],d)for(a.push(','+i),f=1,j=b.properties.length;f0||t.moz.comprehensionExpressionStartsWithAssignment?a=h(a,c):a.push(c)}),b.filter&&(a=h(a,'if'+f),c=this.generateExpression(b.filter,e.Sequence,g),a=h(a,['(',c,')'])),t.moz.comprehensionExpressionStartsWithAssignment||(c=this.generateExpression(b.body,e.Assignment,g),a=h(a,c)),a.push(b.type===k.GeneratorExpression?')':']'),a},ComprehensionBlock:function(b,c,d){var a;return b.left.type===k.VariableDeclaration?a=[b.left.kind,v(),this.generateStatement(b.left.declarations[0],K)]:a=this.generateExpression(b.left,e.Call,g),a=h(a,b.of?'of':'in'),a=h(a,this.generateExpression(b.right,e.Sequence,g)),['for'+f+'(',a,')']},SpreadElement:function(a,b,c){return['...',this.generateExpression(a.argument,e.Assignment,g)]},TaggedTemplateExpression:function(b,d,f){var a=P;f&E||(a=R);var c=[this.generateExpression(b.tag,e.Call,a),this.generateExpression(b.quasi,e.Primary,a6)];return s(c,e.TaggedTemplate,d)},TemplateElement:function(a,b,c){return a.value.raw},TemplateLiteral:function(c,h,i){var a,b,d;for(a=['`'],b=0,d=c.quasis.length;b=0.12.0'},maintainers:[{name:'Yusuke Suzuki',email:'utatane.tea@gmail.com',web:'http://github.com/Constellation'}],repository:{type:'git',url:'http://github.com/estools/escodegen.git'},dependencies:{estraverse:'^1.9.1',esutils:'^2.0.2',esprima:'^2.7.1',optionator:'^0.8.1'},optionalDependencies:{'source-map':'~0.2.0'},devDependencies:{acorn:'^2.7.0',bluebird:'^2.3.11','bower-registry-client':'^0.2.1',chai:'^1.10.0','commonjs-everywhere':'^0.9.7',gulp:'^3.8.10','gulp-eslint':'^0.2.0','gulp-mocha':'^2.0.0',semver:'^5.1.0'},license:'BSD-2-Clause',scripts:{test:'gulp travis','unit-test':'gulp test',lint:'gulp lint',release:'node tools/release.js','build-min':'./node_modules/.bin/cjsify -ma path: tools/entry-point.js > escodegen.browser.min.js',build:'./node_modules/.bin/cjsify -a path: tools/entry-point.js > escodegen.browser.js'}}}),a.define('/node_modules/source-map/lib/source-map.js',function(b,c,d,e){c.SourceMapGenerator=a('/node_modules/source-map/lib/source-map/source-map-generator.js',b).SourceMapGenerator,c.SourceMapConsumer=a('/node_modules/source-map/lib/source-map/source-map-consumer.js',b).SourceMapConsumer,c.SourceNode=a('/node_modules/source-map/lib/source-map/source-node.js',b).SourceNode}),a.define('/node_modules/source-map/lib/source-map/source-node.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(d,i,e){function a(a,c,d,e,f){this.children=[],this.sourceContents={},this.line=a==null?null:a,this.column=c==null?null:c,this.source=d==null?null:d,this.name=f==null?null:f,this[b]=!0,e!=null&&this.add(e)}var f=d('/node_modules/source-map/lib/source-map/source-map-generator.js',e).SourceMapGenerator,c=d('/node_modules/source-map/lib/source-map/util.js',e),g=/(\r?\n)/,h=10,b='$$$isSourceNode$$$';a.fromStringWithSourceMap=function b(n,m,j){function l(b,d){if(b===null||b.source===undefined)e.add(d);else{var f=j?c.join(j,b.source):b.source;e.add(new a(b.originalLine,b.originalColumn,f,d,b.name))}}var e=new a,d=n.split(g),k=function(){var a=d.shift(),b=d.shift()||'';return a+b},i=1,h=0,f=null;return m.eachMapping(function(a){if(f!==null)if(i0&&(f&&l(f,k()),e.add(d.join(''))),m.sources.forEach(function(a){var b=m.sourceContentFor(a);b!=null&&(j!=null&&(a=c.join(j,a)),e.setSourceContent(a,b))}),e},a.prototype.add=function a(c){if(Array.isArray(c))c.forEach(function(a){this.add(a)},this);else if(c[b]||typeof c==='string')c&&this.children.push(c);else throw new TypeError('Expected a SourceNode, string, or an array of SourceNodes and strings. Got '+c);return this},a.prototype.prepend=function a(c){if(Array.isArray(c))for(var d=c.length-1;d>=0;d--)this.prepend(c[d]);else if(c[b]||typeof c==='string')this.children.unshift(c);else throw new TypeError('Expected a SourceNode, string, or an array of SourceNodes and strings. Got '+c);return this},a.prototype.walk=function a(e){var c;for(var d=0,f=this.children.length;d0){for(b=[],c=0;c=0;f--)h=e[f],h==='.'?e.splice(f,1):h==='..'?g++:g>0&&(h===''?(e.splice(f+1,g),g=0):(e.splice(f,2),g--));return a=e.join('/'),a===''&&(a=j?'/':'.'),d?(d.path=a,c(d)):a}function h(h,d){h===''&&(h='.'),d===''&&(d='.');var f=b(d),a=b(h);if(a&&(h=a.path||'/'),f&&!f.scheme)return a&&(f.scheme=a.scheme),c(f);if(f||d.match(e))return d;if(a&&!a.host&&!a.path)return a.host=d,c(a);var i=d.charAt(0)==='/'?d:g(h.replace(/\/+$/,'')+'/'+d);return a?(a.path=i,c(a)):i}function j(a,c){a===''&&(a='.'),a=a.replace(/\/$/,'');var d=b(a);return c.charAt(0)=='/'&&d&&d.path=='/'?c.slice(1):c.indexOf(a+'/')===0?c.substr(a.length+1):c}function k(a){return'$'+a}function l(a){return a.substr(1)}function d(c,d){var a=c||'',b=d||'';return(a>b)-(a0&&(b.splice(a-1,2),a-=2)}function j(b,c){var a;return b&&b.charAt(0)==='.'&&c&&(a=c.split('/'),a=a.slice(0,a.length-1),a=a.concat(b.split('/')),q(a),b=a.join('/')),b}function p(a){return function(b){return j(b,a)}}function o(c){function a(a){b[c]=a}return a.fromText=function(a,b){throw new Error('amdefine does not implement load.fromText')},a}function m(c,h,l){var m,f,a,j;if(c)f=b[c]={},a={id:c,uri:d,exports:f},m=g(i,f,a,c);else{if(k)throw new Error('amdefine with no module ID cannot be called more than once per file.');k=!0,f=e.exports,a=e,m=g(i,f,a,e.id)}h&&(h=h.map(function(a){return m(a)})),typeof l==='function'?j=l.apply(a.exports,h):j=l,j!==undefined&&(a.exports=j,c&&(b[c]=a.exports))}function l(b,a,c){Array.isArray(b)?(c=a,a=b,b=undefined):typeof b!=='string'&&(c=b,b=a=undefined),a&&!Array.isArray(a)&&(c=a,a=undefined),a||(a=['require','exports','module']),b?f[b]=[b,a,c]:m(b,a,c)}var f={},b={},k=!1,n=a('path',e),g,h;return g=function(b,d,a,e){function f(f,g){if(typeof f==='string')return h(b,d,a,f,e);f=f.map(function(c){return h(b,d,a,c,e)}),g&&c.nextTick(function(){g.apply(null,f)})}return f.toUrl=function(b){return b.indexOf('.')===0?j(b,n.dirname(a.filename)):b},f},i=i||function a(){return e.require.apply(e,arguments)},h=function(d,e,i,a,c){var k=a.indexOf('!'),n=a,q,l;if(k===-1)if(a=j(a,c),a==='require')return g(d,e,i,c);else if(a==='exports')return e;else if(a==='module')return i;else if(b.hasOwnProperty(a))return b[a];else if(f[a])return m.apply(null,f[a]),b[a];else if(d)return d(n);else throw new Error('No module with ID: '+a);else return q=a.substring(0,k),a=a.substring(k+1,a.length),l=h(d,e,i,q,c),l.normalize?a=l.normalize(a,p(c)):a=j(a,c),b[a]?b[a]:(l.load(a,g(d,e,i,c),o(a),{}),b[a])},l.require=function(a){return b[a]?b[a]:f[a]?(m.apply(null,f[a]),b[a]):void 0},l.amd={},l}b.exports=e}),a.define('/node_modules/source-map/lib/source-map/source-map-generator.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(e,h,f){function b(b){b||(b={}),this._file=a.getArg(b,'file',null),this._sourceRoot=a.getArg(b,'sourceRoot',null),this._skipValidation=a.getArg(b,'skipValidation',!1),this._sources=new d,this._names=new d,this._mappings=new g,this._sourcesContents=null}var c=e('/node_modules/source-map/lib/source-map/base64-vlq.js',f),a=e('/node_modules/source-map/lib/source-map/util.js',f),d=e('/node_modules/source-map/lib/source-map/array-set.js',f).ArraySet,g=e('/node_modules/source-map/lib/source-map/mapping-list.js',f).MappingList;b.prototype._version=3,b.fromSourceMap=function c(d){var e=d.sourceRoot,f=new b({file:d.file,sourceRoot:e});return d.eachMapping(function(b){var c={generated:{line:b.generatedLine,column:b.generatedColumn}};b.source!=null&&(c.source=b.source,e!=null&&(c.source=a.relative(e,c.source)),c.original={line:b.originalLine,column:b.originalColumn},b.name!=null&&(c.name=b.name)),f.addMapping(c)}),d.sources.forEach(function(b){var a=d.sourceContentFor(b);a!=null&&f.setSourceContent(b,a)}),f},b.prototype.addMapping=function b(f){var g=a.getArg(f,'generated'),c=a.getArg(f,'original',null),d=a.getArg(f,'source',null),e=a.getArg(f,'name',null);this._skipValidation||this._validateMapping(g,c,d,e),d!=null&&!this._sources.has(d)&&this._sources.add(d),e!=null&&!this._names.has(e)&&this._names.add(e),this._mappings.add({generatedLine:g.line,generatedColumn:g.column,originalLine:c!=null&&c.line,originalColumn:c!=null&&c.column,source:d,name:e})},b.prototype.setSourceContent=function b(e,d){var c=e;this._sourceRoot!=null&&(c=a.relative(this._sourceRoot,c)),d!=null?(this._sourcesContents||(this._sourcesContents={}),this._sourcesContents[a.toSetString(c)]=d):this._sourcesContents&&(delete this._sourcesContents[a.toSetString(c)],Object.keys(this._sourcesContents).length===0&&(this._sourcesContents=null))},b.prototype.applySourceMap=function b(e,j,g){var f=j;if(j==null){if(e.file==null)throw new Error('SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, or the source map\'s "file" property. Both were omitted.');f=e.file}var c=this._sourceRoot;c!=null&&(f=a.relative(c,f));var h=new d,i=new d;this._mappings.unsortedForEach(function(b){if(b.source===f&&b.originalLine!=null){var d=e.originalPositionFor({line:b.originalLine,column:b.originalColumn});d.source!=null&&(b.source=d.source,g!=null&&(b.source=a.join(g,b.source)),c!=null&&(b.source=a.relative(c,b.source)),b.originalLine=d.line,b.originalColumn=d.column,d.name!=null&&(b.name=d.name))}var j=b.source;j!=null&&!h.has(j)&&h.add(j);var k=b.name;k!=null&&!i.has(k)&&i.add(k)},this),this._sources=h,this._names=i,e.sources.forEach(function(b){var d=e.sourceContentFor(b);d!=null&&(g!=null&&(b=a.join(g,b)),c!=null&&(b=a.relative(c,b)),this.setSourceContent(b,d))},this)},b.prototype._validateMapping=function a(b,c,d,e){if(b&&'line'in b&&'column'in b&&b.line>0&&b.column>=0&&!c&&!d&&!e)return;else if(b&&'line'in b&&'column'in b&&c&&'line'in c&&'column'in c&&b.line>0&&b.column>=0&&c.line>0&&c.column>=0&&d)return;else throw new Error('Invalid mapping: '+JSON.stringify({generated:b,source:d,original:c,name:e}))},b.prototype._serializeMappings=function b(){var h=0,g=1,k=0,l=0,m=0,j=0,e='',d,i=this._mappings.toArray();for(var f=0,n=i.length;f0){if(!a.compareByGeneratedPositions(d,i[f-1]))continue;e+=','}e+=c.encode(d.generatedColumn-h),h=d.generatedColumn,d.source!=null&&(e+=c.encode(this._sources.indexOf(d.source)-j),j=this._sources.indexOf(d.source),e+=c.encode(d.originalLine-1-l),l=d.originalLine-1,e+=c.encode(d.originalColumn-k),k=d.originalColumn,d.name!=null&&(e+=c.encode(this._names.indexOf(d.name)-m),m=this._names.indexOf(d.name)))}return e},b.prototype._generateSourcesContent=function b(d,c){return d.map(function(b){if(!this._sourcesContents)return null;c!=null&&(b=a.relative(c,b));var d=a.toSetString(b);return Object.prototype.hasOwnProperty.call(this._sourcesContents,d)?this._sourcesContents[d]:null},this)},b.prototype.toJSON=function a(){var b={version:this._version,sources:this._sources.toArray(),names:this._names.toArray(),mappings:this._serializeMappings()};return this._file!=null&&(b.file=this._file),this._sourceRoot!=null&&(b.sourceRoot=this._sourceRoot),this._sourcesContents&&(b.sourcesContent=this._generateSourcesContent(b.sources,b.sourceRoot)),b},b.prototype.toString=function a(){return JSON.stringify(this)},h.SourceMapGenerator=b})}),a.define('/node_modules/source-map/lib/source-map/mapping-list.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(c,d,e){function f(a,c){var d=a.generatedLine,e=c.generatedLine,f=a.generatedColumn,g=c.generatedColumn;return e>d||e==d&&g>=f||b.compareByGeneratedPositions(a,c)<=0}function a(){this._array=[],this._sorted=!0,this._last={generatedLine:-1,generatedColumn:0}}var b=c('/node_modules/source-map/lib/source-map/util.js',e);a.prototype.unsortedForEach=function a(b,c){this._array.forEach(b,c)},a.prototype.add=function a(b){f(this._last,b)?(this._last=b,this._array.push(b)):(this._sorted=!1,this._array.push(b))},a.prototype.toArray=function a(){return this._sorted||(this._array.sort(b.compareByGeneratedPositions),this._sorted=!0),this._array},d.MappingList=a})}),a.define('/node_modules/source-map/lib/source-map/array-set.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(c,d,e){function a(){this._array=[],this._set={}}var b=c('/node_modules/source-map/lib/source-map/util.js',e);a.fromArray=function b(e,g){var d=new a;for(var c=0,f=e.length;c=0&&b>1;return c?-a:a}var c=j('/node_modules/source-map/lib/source-map/base64.js',h),a=5,d=1<>>=a,f>0&&(h|=b),g+=c.encode(h);while(f>0);return g},f.decode=function d(i,l){var f=0,m=i.length,j=0,k=0,n,h;do{if(f>=m)throw new Error('Expected more digits in base 64 VLQ value.');h=c.decode(i.charAt(f++)),n=!!(h&b),h&=e,j+=h<=0){var c=this._originalMappings[e];while(c&&c.originalLine===d.originalLine)f.push({line:b.getArg(c,'generatedLine',null),column:b.getArg(c,'generatedColumn',null),lastColumn:b.getArg(c,'lastGeneratedColumn',null)}),c=this._originalMappings[--e]}return f.reverse()},e.SourceMapConsumer=a})}),a.define('/node_modules/source-map/lib/source-map/basic-source-map-consumer.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(d,i,e){function b(d){var b=d;typeof d==='string'&&(b=JSON.parse(d.replace(/^\)\]\}'/,'')));var e=a.getArg(b,'version'),c=a.getArg(b,'sources'),g=a.getArg(b,'names',[]),h=a.getArg(b,'sourceRoot',null),i=a.getArg(b,'sourcesContent',null),j=a.getArg(b,'mappings'),k=a.getArg(b,'file',null);if(e!=this._version)throw new Error('Unsupported version: '+e);c=c.map(a.normalize),this._names=f.fromArray(g,!0),this._sources=f.fromArray(c,!0),this.sourceRoot=h,this.sourcesContent=i,this._mappings=j,this.file=k}var a=d('/node_modules/source-map/lib/source-map/util.js',e),h=d('/node_modules/source-map/lib/source-map/binary-search.js',e),f=d('/node_modules/source-map/lib/source-map/array-set.js',e).ArraySet,c=d('/node_modules/source-map/lib/source-map/base64-vlq.js',e),g=d('/node_modules/source-map/lib/source-map/source-map-consumer.js',e).SourceMapConsumer;b.prototype=Object.create(g.prototype),b.prototype.consumer=g,b.fromSourceMap=function c(e){var d=Object.create(b.prototype);return d._names=f.fromArray(e._names.toArray(),!0),d._sources=f.fromArray(e._sources.toArray(),!0),d.sourceRoot=e._sourceRoot,d.sourcesContent=e._generateSourcesContent(d._sources.toArray(),d.sourceRoot),d.file=e._file,d.__generatedMappings=e._mappings.toArray().slice(),d.__originalMappings=e._mappings.toArray().slice().sort(a.compareByOriginalPositions),d},b.prototype._version=3,Object.defineProperty(b.prototype,'sources',{get:function(){return this._sources.toArray().map(function(b){return this.sourceRoot!=null?a.join(this.sourceRoot,b):b},this)}}),b.prototype._parseMappings=function b(m,n){var j=1,g=0,i=0,h=0,k=0,l=0,d=m,e={},f;while(d.length>0)if(d.charAt(0)===';')j++,d=d.slice(1),g=0;else if(d.charAt(0)===',')d=d.slice(1);else{if(f={},f.generatedLine=j,c.decode(d,e),f.generatedColumn=g+e.value,g=f.generatedColumn,d=e.rest,d.length>0&&!this._nextCharIsMappingSeparator(d)){if(c.decode(d,e),f.source=this._sources.at(k+e.value),k+=e.value,d=e.rest,d.length===0||this._nextCharIsMappingSeparator(d))throw new Error('Found a source, but no line and column');if(c.decode(d,e),f.originalLine=i+e.value,i=f.originalLine,f.originalLine+=1,d=e.rest,d.length===0||this._nextCharIsMappingSeparator(d))throw new Error('Found a source and line, but no column');c.decode(d,e),f.originalColumn=h+e.value,h=f.originalColumn,d=e.rest,d.length>0&&!this._nextCharIsMappingSeparator(d)&&(c.decode(d,e),f.name=this._names.at(l+e.value),l+=e.value,d=e.rest)}this.__generatedMappings.push(f),typeof f.originalLine==='number'&&this.__originalMappings.push(f)}this.__generatedMappings.sort(a.compareByGeneratedPositions),this.__originalMappings.sort(a.compareByOriginalPositions)},b.prototype._findMapping=function a(b,e,c,d,f){if(b[c]<=0)throw new TypeError('Line must be greater than or equal to 1, got '+b[c]);if(b[d]<0)throw new TypeError('Column must be greater than or equal to 0, got '+b[d]);return h.search(b,e,f)},b.prototype.computeColumnSpans=function a(){for(var b=0;b=0){var c=this._generatedMappings[f];if(c.generatedLine===e.generatedLine){var d=a.getArg(c,'source',null);return d!=null&&this.sourceRoot!=null&&(d=a.join(this.sourceRoot,d)),{source:d,line:a.getArg(c,'originalLine',null),column:a.getArg(c,'originalColumn',null),name:a.getArg(c,'name',null)}}}return{source:null,line:null,column:null,name:null}},b.prototype.sourceContentFor=function b(c,f){if(!this.sourcesContent)return null;if(this.sourceRoot!=null&&(c=a.relative(this.sourceRoot,c)),this._sources.has(c))return this.sourcesContent[this._sources.indexOf(c)];var d;if(this.sourceRoot!=null&&(d=a.urlParse(this.sourceRoot))){var e=c.replace(/^file:\/\//,'');if(d.scheme=='file'&&this._sources.has(e))return this.sourcesContent[this._sources.indexOf(e)];if((!d.path||d.path=='/')&&this._sources.has('/'+c))return this.sourcesContent[this._sources.indexOf('/'+c)]}if(f)return null;else throw new Error('"'+c+'" is not in the SourceMap.')},b.prototype.generatedPositionFor=function b(e){var c={source:a.getArg(e,'source'),originalLine:a.getArg(e,'line'),originalColumn:a.getArg(e,'column')};this.sourceRoot!=null&&(c.source=a.relative(this.sourceRoot,c.source));var f=this._findMapping(c,this._originalMappings,'originalLine','originalColumn',a.compareByOriginalPositions);if(f>=0){var d=this._originalMappings[f];return{line:a.getArg(d,'generatedLine',null),column:a.getArg(d,'generatedColumn',null),lastColumn:a.getArg(d,'lastGeneratedColumn',null)}}return{line:null,column:null,lastColumn:null}},i.BasicSourceMapConsumer=b})}),a.define('/node_modules/source-map/lib/source-map/binary-search.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(c,b,d){function a(c,d,e,f,g){var b=Math.floor((d-c)/2)+c,h=g(e,f[b],!0);return h===0?b:h>0?d-b>1?a(b,d,e,f,g):b:b-c>1?a(c,b,e,f,g):c<0?-1:c}b.search=function b(d,c,e){return c.length===0?-1:a(-1,c.length,d,c,e)}})}),a.define('/node_modules/source-map/lib/source-map/indexed-source-map-consumer.js',function(c,d,e,f){if(typeof b!=='function')var b=a('/node_modules/amdefine/amdefine.js',c)(c,a);b(function(c,g,d){function b(d){var c=d;typeof d==='string'&&(c=JSON.parse(d.replace(/^\)\]\}'/,'')));var f=a.getArg(c,'version'),g=a.getArg(c,'sections');if(f!=this._version)throw new Error('Unsupported version: '+f);var b={line:-1,column:0};this._sections=g.map(function(f){if(f.url)throw new Error('Support for url field in sections not implemented.');var c=a.getArg(f,'offset'),d=a.getArg(c,'line'),g=a.getArg(c,'column');if(d=f)return!1;if(e=d.charCodeAt(a),!(56320<=e&&e<=57343))return!1;b=l(b,e)}if(!g(b))return!1;g=c.isIdentifierPartES6}return!0}function n(a,b){return h(a)&&!g(a,b)}function k(a,b){return i(a)&&!e(a,b)}c=a('/node_modules/esutils/lib/code.js',b),b.exports={isKeywordES5:f,isKeywordES6:d,isReservedWordES5:g,isReservedWordES6:e,isRestrictedWord:j,isIdentifierNameES5:h,isIdentifierNameES6:i,isIdentifierES5:n,isIdentifierES6:k}}()}),a.define('/node_modules/esutils/lib/code.js',function(a,b,c,d){!function(g,f,h,c,d,b){'use strict';function n(a){return 48<=a&&a<=57}function i(a){return 48<=a&&a<=57||97<=a&&a<=102||65<=a&&a<=70}function k(a){return a>=48&&a<=55}function l(a){return a===32||a===9||a===11||a===12||a===160||a>=5760&&h.indexOf(a)>=0}function m(a){return a===10||a===13||a===8232||a===8233}function e(a){if(a<=65535)return String.fromCharCode(a);var b=String.fromCharCode(Math.floor((a-65536)/1024)+55296),c=String.fromCharCode((a-65536)%1024+56320);return b+c}function o(a){return a<128?c[a]:f.NonAsciiIdentifierStart.test(e(a))}function p(a){return a<128?d[a]:f.NonAsciiIdentifierPart.test(e(a))}function q(a){return a<128?c[a]:g.NonAsciiIdentifierStart.test(e(a))}function j(a){return a<128?d[a]:g.NonAsciiIdentifierPart.test(e(a))}for(f={NonAsciiIdentifierStart:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/,NonAsciiIdentifierPart:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/},g={NonAsciiIdentifierStart:/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/,NonAsciiIdentifierPart:/[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDD0-\uDDDA\uDE00-\uDE11\uDE13-\uDE37\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF01-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|\uD809[\uDC00-\uDC6E]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/},h=[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279],c=new Array(128),b=0;b<128;++b)c[b]=b>=97&&b<=122||b>=65&&b<=90||b===36||b===95;for(d=new Array(128),b=0;b<128;++b)d[b]=b>=97&&b<=122||b>=65&&b<=90||b>=48&&b<=57||b===36||b===95;a.exports={isDecimalDigit:n,isHexDigit:i,isOctalDigit:k,isWhiteSpace:l,isLineTerminator:m,isIdentifierStartES5:o,isIdentifierPartES5:p,isIdentifierStartES6:q,isIdentifierPartES6:j}}()}),a.define('/node_modules/esutils/lib/ast.js',function(a,b,c,d){!function(){'use strict';function d(a){if(a==null)return!1;switch(a.type){case'ArrayExpression':case'AssignmentExpression':case'BinaryExpression':case'CallExpression':case'ConditionalExpression':case'FunctionExpression':case'Identifier':case'Literal':case'LogicalExpression':case'MemberExpression':case'NewExpression':case'ObjectExpression':case'SequenceExpression':case'ThisExpression':case'UnaryExpression':case'UpdateExpression':return!0}return!1}function e(a){if(a==null)return!1;switch(a.type){case'DoWhileStatement':case'ForInStatement':case'ForStatement':case'WhileStatement':return!0}return!1}function b(a){if(a==null)return!1;switch(a.type){case'BlockStatement':case'BreakStatement':case'ContinueStatement':case'DebuggerStatement':case'DoWhileStatement':case'EmptyStatement':case'ExpressionStatement':case'ForInStatement':case'ForStatement':case'IfStatement':case'LabeledStatement':case'ReturnStatement':case'SwitchStatement':case'ThrowStatement':case'TryStatement':case'VariableDeclaration':case'WhileStatement':case'WithStatement':return!0}return!1}function f(a){return b(a)||a!=null&&a.type==='FunctionDeclaration'}function c(a){switch(a.type){case'IfStatement':return a.alternate!=null?a.alternate:a.consequent;case'LabeledStatement':case'ForStatement':case'ForInStatement':case'WhileStatement':case'WithStatement':return a.body}return null}function g(b){var a;if(b.type!=='IfStatement')return!1;if(b.alternate==null)return!1;a=b.consequent;do{if(a.type==='IfStatement'&&a.alternate==null)return!0;a=c(a)}while(a);return!1}a.exports={isExpression:d,isStatement:b,isIterationStatement:e,isSourceElement:f,isProblematicIfStatement:g,trailingStatement:c}}()}),a.define('/node_modules/estraverse/estraverse.js',function(b,a,c,d){!function(c,b){'use strict';typeof define==='function'&&define.amd?define(['exports'],b):a!==void 0?b(a):b(c.estraverse={})}(this,function a(d){'use strict';function s(){}function p(d){var c={},a,b;for(a in d)d.hasOwnProperty(a)&&(b=d[a],typeof b==='object'&&b!==null?c[a]=p(b):c[a]=b);return c}function y(b){var c={},a;for(a in b)b.hasOwnProperty(a)&&(c[a]=b[a]);return c}function x(e,f){var b,a,c,d;a=e.length,c=0;while(a)b=a>>>1,d=c+b,f(e[d])?a=b:(c=d+1,a-=b+1);return c}function t(e,f){var b,a,c,d;a=e.length,c=0;while(a)b=a>>>1,d=c+b,f(e[d])?(c=d+1,a-=b+1):a=b;return c}function u(d,e){var b=l(e),c,a,f;for(a=0,f=b.length;aa.range[0]}),a.extendedRange=[a.range[0],a.range[1]],b!==c.length&&(a.extendedRange[1]=c[b].range[0]),b-=1,b>=0&&(a.extendedRange[0]=c[b].range[1]),a}function v(d,e,h){var a=[],g,f,c,b;if(!d.range)throw new Error('attachComments needs range information');if(!h.length){if(e.length){for(c=0,f=e.length;cc.range[0])break;d.extendedRange[1]===c.range[0]?(c.leadingComments||(c.leadingComments=[]),c.leadingComments.push(d),a.splice(b,1)):b+=1}return b===a.length?j.Break:a[b].extendedRange[0]>c.range[1]?j.Skip:void 0}}),b=0,o(d,{leave:function(c){var d;while(bc.range[1]?j.Skip:void 0}}),d}var m,h,j,n,r,l,c,g,f;return h=Array.isArray,h||(h=function a(b){return Object.prototype.toString.call(b)==='[object Array]'}),s(y),s(t),r=Object.create||function(){function a(){}return function(b){return a.prototype=b,new a}}(),l=Object.keys||function(c){var a=[],b;for(b in c)a.push(b);return a},m={AssignmentExpression:'AssignmentExpression',ArrayExpression:'ArrayExpression',ArrayPattern:'ArrayPattern',ArrowFunctionExpression:'ArrowFunctionExpression',AwaitExpression:'AwaitExpression',BlockStatement:'BlockStatement',BinaryExpression:'BinaryExpression',BreakStatement:'BreakStatement',CallExpression:'CallExpression',CatchClause:'CatchClause',ClassBody:'ClassBody',ClassDeclaration:'ClassDeclaration',ClassExpression:'ClassExpression',ComprehensionBlock:'ComprehensionBlock',ComprehensionExpression:'ComprehensionExpression',ConditionalExpression:'ConditionalExpression',ContinueStatement:'ContinueStatement',DebuggerStatement:'DebuggerStatement',DirectiveStatement:'DirectiveStatement',DoWhileStatement:'DoWhileStatement',EmptyStatement:'EmptyStatement',ExportBatchSpecifier:'ExportBatchSpecifier',ExportDeclaration:'ExportDeclaration',ExportSpecifier:'ExportSpecifier',ExpressionStatement:'ExpressionStatement',ForStatement:'ForStatement',ForInStatement:'ForInStatement',ForOfStatement:'ForOfStatement',FunctionDeclaration:'FunctionDeclaration',FunctionExpression:'FunctionExpression',GeneratorExpression:'GeneratorExpression',Identifier:'Identifier',IfStatement:'IfStatement',ImportDeclaration:'ImportDeclaration',ImportDefaultSpecifier:'ImportDefaultSpecifier',ImportNamespaceSpecifier:'ImportNamespaceSpecifier',ImportSpecifier:'ImportSpecifier',Literal:'Literal',LabeledStatement:'LabeledStatement',LogicalExpression:'LogicalExpression',MemberExpression:'MemberExpression',MethodDefinition:'MethodDefinition',ModuleSpecifier:'ModuleSpecifier',NewExpression:'NewExpression',ObjectExpression:'ObjectExpression',ObjectPattern:'ObjectPattern',Program:'Program',Property:'Property',ReturnStatement:'ReturnStatement',SequenceExpression:'SequenceExpression',SpreadElement:'SpreadElement',SwitchStatement:'SwitchStatement',SwitchCase:'SwitchCase',TaggedTemplateExpression:'TaggedTemplateExpression',TemplateElement:'TemplateElement',TemplateLiteral:'TemplateLiteral',ThisExpression:'ThisExpression',ThrowStatement:'ThrowStatement',TryStatement:'TryStatement',UnaryExpression:'UnaryExpression',UpdateExpression:'UpdateExpression',VariableDeclaration:'VariableDeclaration',VariableDeclarator:'VariableDeclarator',WhileStatement:'WhileStatement',WithStatement:'WithStatement',YieldExpression:'YieldExpression'},n={AssignmentExpression:['left','right'],ArrayExpression:['elements'],ArrayPattern:['elements'],ArrowFunctionExpression:['params','defaults','rest','body'],AwaitExpression:['argument'],BlockStatement:['body'],BinaryExpression:['left','right'],BreakStatement:['label'],CallExpression:['callee','arguments'],CatchClause:['param','body'],ClassBody:['body'],ClassDeclaration:['id','body','superClass'],ClassExpression:['id','body','superClass'],ComprehensionBlock:['left','right'],ComprehensionExpression:['blocks','filter','body'],ConditionalExpression:['test','consequent','alternate'],ContinueStatement:['label'],DebuggerStatement:[],DirectiveStatement:[],DoWhileStatement:['body','test'],EmptyStatement:[],ExportBatchSpecifier:[],ExportDeclaration:['declaration','specifiers','source'],ExportSpecifier:['id','name'],ExpressionStatement:['expression'],ForStatement:['init','test','update','body'],ForInStatement:['left','right','body'],ForOfStatement:['left','right','body'],FunctionDeclaration:['id','params','defaults','rest','body'],FunctionExpression:['id','params','defaults','rest','body'],GeneratorExpression:['blocks','filter','body'],Identifier:[],IfStatement:['test','consequent','alternate'],ImportDeclaration:['specifiers','source'],ImportDefaultSpecifier:['id'],ImportNamespaceSpecifier:['id'],ImportSpecifier:['id','name'],Literal:[],LabeledStatement:['label','body'],LogicalExpression:['left','right'],MemberExpression:['object','property'],MethodDefinition:['key','value'],ModuleSpecifier:[],NewExpression:['callee','arguments'],ObjectExpression:['properties'],ObjectPattern:['properties'],Program:['body'],Property:['key','value'],ReturnStatement:['argument'],SequenceExpression:['expressions'],SpreadElement:['argument'],SwitchStatement:['discriminant','cases'],SwitchCase:['test','consequent'],TaggedTemplateExpression:['tag','quasi'],TemplateElement:[],TemplateLiteral:['quasis','expressions'],ThisExpression:[],ThrowStatement:['argument'],TryStatement:['block','handlers','handler','guardedHandlers','finalizer'],UnaryExpression:['argument'],UpdateExpression:['argument'],VariableDeclaration:['declarations'],VariableDeclarator:['id','init'],WhileStatement:['test','body'],WithStatement:['object','body'],YieldExpression:['argument']},c={},g={},f={},j={Break:c,Skip:g,Remove:f},i.prototype.replace=function a(b){this.parent[this.key]=b},i.prototype.remove=function a(){return h(this.parent)?(this.parent.splice(this.key,1),!0):(this.replace(null),!1)},b.prototype.path=function a(){function e(b,a){if(h(a))for(c=0,g=a.length;c=0){if(n=j[p],d=o[n],!d)continue;if(h(d)){f=d.length;while((f-=1)>=0){if(!d[f])continue;if(q(s,j[p]))b=new e(d[f],[n,f],'Property',null);else if(k(d[f]))b=new e(d[f],[n,f],null,null);else continue;i.push(b)}}else k(d)&&i.push(new e(d,n,null,null))}}}},b.prototype.replace=function a(w,x){function z(b){var c,d,a,e;if(b.ref.remove()){d=b.ref.key,e=b.ref.parent,c=n.length;while(c--)if(a=n[c],a.ref&&a.ref.parent===e){if(a.ref.key=0){if(r=o[u],j=p[r],!j)continue;if(h(j)){m=j.length;while((m-=1)>=0){if(!j[m])continue;if(q(t,o[u]))b=new e(j[m],[r,m],'Property',new i(j,m));else if(k(j[m]))b=new e(j[m],[r,m],null,new i(j,m));else continue;n.push(b)}}else k(j)&&n.push(new e(j,r,null,new i(p,r)))}}return s.root},d.version='1.8.1-dev',d.Syntax=m,d.traverse=o,d.replace=w,d.attachComments=v,d.VisitorKeys=n,d.VisitorOption=j,d.Controller=b,d.cloneEnvironment=function(){return a({})},d})}),a('/tools/entry-point.js')}.call(this,this)) \ No newline at end of file diff --git a/share/server/60/esprima.js b/share/server/60/esprima.js deleted file mode 100644 index ae8b47783..000000000 --- a/share/server/60/esprima.js +++ /dev/null @@ -1,6711 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { -/* istanbul ignore next */ - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); -/* istanbul ignore next */ - else if(typeof exports === 'object') - exports["esprima"] = factory(); - else - root["esprima"] = factory(); -})(this, function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; - -/******/ // The require function -/******/ function __webpack_require__(moduleId) { - -/******/ // Check if module is in cache -/* istanbul ignore if */ -/******/ if(installedModules[moduleId]) -/******/ return installedModules[moduleId].exports; - -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ exports: {}, -/******/ id: moduleId, -/******/ loaded: false -/******/ }; - -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); - -/******/ // Flag the module as loaded -/******/ module.loaded = true; - -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } - - -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; - -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; - -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; - -/******/ // Load entry module and return exports -/******/ return __webpack_require__(0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - /* - Copyright JS Foundation and other contributors, https://js.foundation/ - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - Object.defineProperty(exports, "__esModule", { value: true }); - var comment_handler_1 = __webpack_require__(1); - var jsx_parser_1 = __webpack_require__(3); - var parser_1 = __webpack_require__(8); - var tokenizer_1 = __webpack_require__(15); - function parse(code, options, delegate) { - var commentHandler = null; - var proxyDelegate = function (node, metadata) { - if (delegate) { - delegate(node, metadata); - } - if (commentHandler) { - commentHandler.visit(node, metadata); - } - }; - var parserDelegate = (typeof delegate === 'function') ? proxyDelegate : null; - var collectComment = false; - if (options) { - collectComment = (typeof options.comment === 'boolean' && options.comment); - var attachComment = (typeof options.attachComment === 'boolean' && options.attachComment); - if (collectComment || attachComment) { - commentHandler = new comment_handler_1.CommentHandler(); - commentHandler.attach = attachComment; - options.comment = true; - parserDelegate = proxyDelegate; - } - } - var isModule = false; - if (options && typeof options.sourceType === 'string') { - isModule = (options.sourceType === 'module'); - } - var parser; - if (options && typeof options.jsx === 'boolean' && options.jsx) { - parser = new jsx_parser_1.JSXParser(code, options, parserDelegate); - } - else { - parser = new parser_1.Parser(code, options, parserDelegate); - } - var program = isModule ? parser.parseModule() : parser.parseScript(); - var ast = program; - if (collectComment && commentHandler) { - ast.comments = commentHandler.comments; - } - if (parser.config.tokens) { - ast.tokens = parser.tokens; - } - if (parser.config.tolerant) { - ast.errors = parser.errorHandler.errors; - } - return ast; - } - exports.parse = parse; - function parseModule(code, options, delegate) { - var parsingOptions = options || {}; - parsingOptions.sourceType = 'module'; - return parse(code, parsingOptions, delegate); - } - exports.parseModule = parseModule; - function parseScript(code, options, delegate) { - var parsingOptions = options || {}; - parsingOptions.sourceType = 'script'; - return parse(code, parsingOptions, delegate); - } - exports.parseScript = parseScript; - function tokenize(code, options, delegate) { - var tokenizer = new tokenizer_1.Tokenizer(code, options); - var tokens; - tokens = []; - try { - while (true) { - var token = tokenizer.getNextToken(); - if (!token) { - break; - } - if (delegate) { - token = delegate(token); - } - tokens.push(token); - } - } - catch (e) { - tokenizer.errorHandler.tolerate(e); - } - if (tokenizer.errorHandler.tolerant) { - tokens.errors = tokenizer.errors(); - } - return tokens; - } - exports.tokenize = tokenize; - var syntax_1 = __webpack_require__(2); - exports.Syntax = syntax_1.Syntax; - // Sync with *.json manifests. - exports.version = '4.0.1'; - - -/***/ }, -/* 1 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var syntax_1 = __webpack_require__(2); - var CommentHandler = (function () { - function CommentHandler() { - this.attach = false; - this.comments = []; - this.stack = []; - this.leading = []; - this.trailing = []; - } - CommentHandler.prototype.insertInnerComments = function (node, metadata) { - // innnerComments for properties empty block - // `function a() {/** comments **\/}` - if (node.type === syntax_1.Syntax.BlockStatement && node.body.length === 0) { - var innerComments = []; - for (var i = this.leading.length - 1; i >= 0; --i) { - var entry = this.leading[i]; - if (metadata.end.offset >= entry.start) { - innerComments.unshift(entry.comment); - this.leading.splice(i, 1); - this.trailing.splice(i, 1); - } - } - if (innerComments.length) { - node.innerComments = innerComments; - } - } - }; - CommentHandler.prototype.findTrailingComments = function (metadata) { - var trailingComments = []; - if (this.trailing.length > 0) { - for (var i = this.trailing.length - 1; i >= 0; --i) { - var entry_1 = this.trailing[i]; - if (entry_1.start >= metadata.end.offset) { - trailingComments.unshift(entry_1.comment); - } - } - this.trailing.length = 0; - return trailingComments; - } - var entry = this.stack[this.stack.length - 1]; - if (entry && entry.node.trailingComments) { - var firstComment = entry.node.trailingComments[0]; - if (firstComment && firstComment.range[0] >= metadata.end.offset) { - trailingComments = entry.node.trailingComments; - delete entry.node.trailingComments; - } - } - return trailingComments; - }; - CommentHandler.prototype.findLeadingComments = function (metadata) { - var leadingComments = []; - var target; - while (this.stack.length > 0) { - var entry = this.stack[this.stack.length - 1]; - if (entry && entry.start >= metadata.start.offset) { - target = entry.node; - this.stack.pop(); - } - else { - break; - } - } - if (target) { - var count = target.leadingComments ? target.leadingComments.length : 0; - for (var i = count - 1; i >= 0; --i) { - var comment = target.leadingComments[i]; - if (comment.range[1] <= metadata.start.offset) { - leadingComments.unshift(comment); - target.leadingComments.splice(i, 1); - } - } - if (target.leadingComments && target.leadingComments.length === 0) { - delete target.leadingComments; - } - return leadingComments; - } - for (var i = this.leading.length - 1; i >= 0; --i) { - var entry = this.leading[i]; - if (entry.start <= metadata.start.offset) { - leadingComments.unshift(entry.comment); - this.leading.splice(i, 1); - } - } - return leadingComments; - }; - CommentHandler.prototype.visitNode = function (node, metadata) { - if (node.type === syntax_1.Syntax.Program && node.body.length > 0) { - return; - } - this.insertInnerComments(node, metadata); - var trailingComments = this.findTrailingComments(metadata); - var leadingComments = this.findLeadingComments(metadata); - if (leadingComments.length > 0) { - node.leadingComments = leadingComments; - } - if (trailingComments.length > 0) { - node.trailingComments = trailingComments; - } - this.stack.push({ - node: node, - start: metadata.start.offset - }); - }; - CommentHandler.prototype.visitComment = function (node, metadata) { - var type = (node.type[0] === 'L') ? 'Line' : 'Block'; - var comment = { - type: type, - value: node.value - }; - if (node.range) { - comment.range = node.range; - } - if (node.loc) { - comment.loc = node.loc; - } - this.comments.push(comment); - if (this.attach) { - var entry = { - comment: { - type: type, - value: node.value, - range: [metadata.start.offset, metadata.end.offset] - }, - start: metadata.start.offset - }; - if (node.loc) { - entry.comment.loc = node.loc; - } - node.type = type; - this.leading.push(entry); - this.trailing.push(entry); - } - }; - CommentHandler.prototype.visit = function (node, metadata) { - if (node.type === 'LineComment') { - this.visitComment(node, metadata); - } - else if (node.type === 'BlockComment') { - this.visitComment(node, metadata); - } - else if (this.attach) { - this.visitNode(node, metadata); - } - }; - return CommentHandler; - }()); - exports.CommentHandler = CommentHandler; - - -/***/ }, -/* 2 */ -/***/ function(module, exports) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.Syntax = { - AssignmentExpression: 'AssignmentExpression', - AssignmentPattern: 'AssignmentPattern', - ArrayExpression: 'ArrayExpression', - ArrayPattern: 'ArrayPattern', - ArrowFunctionExpression: 'ArrowFunctionExpression', - AwaitExpression: 'AwaitExpression', - BlockStatement: 'BlockStatement', - BinaryExpression: 'BinaryExpression', - BreakStatement: 'BreakStatement', - CallExpression: 'CallExpression', - CatchClause: 'CatchClause', - ClassBody: 'ClassBody', - ClassDeclaration: 'ClassDeclaration', - ClassExpression: 'ClassExpression', - ConditionalExpression: 'ConditionalExpression', - ContinueStatement: 'ContinueStatement', - DoWhileStatement: 'DoWhileStatement', - DebuggerStatement: 'DebuggerStatement', - EmptyStatement: 'EmptyStatement', - ExportAllDeclaration: 'ExportAllDeclaration', - ExportDefaultDeclaration: 'ExportDefaultDeclaration', - ExportNamedDeclaration: 'ExportNamedDeclaration', - ExportSpecifier: 'ExportSpecifier', - ExpressionStatement: 'ExpressionStatement', - ForStatement: 'ForStatement', - ForOfStatement: 'ForOfStatement', - ForInStatement: 'ForInStatement', - FunctionDeclaration: 'FunctionDeclaration', - FunctionExpression: 'FunctionExpression', - Identifier: 'Identifier', - IfStatement: 'IfStatement', - ImportDeclaration: 'ImportDeclaration', - ImportDefaultSpecifier: 'ImportDefaultSpecifier', - ImportNamespaceSpecifier: 'ImportNamespaceSpecifier', - ImportSpecifier: 'ImportSpecifier', - Literal: 'Literal', - LabeledStatement: 'LabeledStatement', - LogicalExpression: 'LogicalExpression', - MemberExpression: 'MemberExpression', - MetaProperty: 'MetaProperty', - MethodDefinition: 'MethodDefinition', - NewExpression: 'NewExpression', - ObjectExpression: 'ObjectExpression', - ObjectPattern: 'ObjectPattern', - Program: 'Program', - Property: 'Property', - RestElement: 'RestElement', - ReturnStatement: 'ReturnStatement', - SequenceExpression: 'SequenceExpression', - SpreadElement: 'SpreadElement', - Super: 'Super', - SwitchCase: 'SwitchCase', - SwitchStatement: 'SwitchStatement', - TaggedTemplateExpression: 'TaggedTemplateExpression', - TemplateElement: 'TemplateElement', - TemplateLiteral: 'TemplateLiteral', - ThisExpression: 'ThisExpression', - ThrowStatement: 'ThrowStatement', - TryStatement: 'TryStatement', - UnaryExpression: 'UnaryExpression', - UpdateExpression: 'UpdateExpression', - VariableDeclaration: 'VariableDeclaration', - VariableDeclarator: 'VariableDeclarator', - WhileStatement: 'WhileStatement', - WithStatement: 'WithStatement', - YieldExpression: 'YieldExpression' - }; - - -/***/ }, -/* 3 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; -/* istanbul ignore next */ - var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; - })(); - Object.defineProperty(exports, "__esModule", { value: true }); - var character_1 = __webpack_require__(4); - var JSXNode = __webpack_require__(5); - var jsx_syntax_1 = __webpack_require__(6); - var Node = __webpack_require__(7); - var parser_1 = __webpack_require__(8); - var token_1 = __webpack_require__(13); - var xhtml_entities_1 = __webpack_require__(14); - token_1.TokenName[100 /* Identifier */] = 'JSXIdentifier'; - token_1.TokenName[101 /* Text */] = 'JSXText'; - // Fully qualified element name, e.g. returns "svg:path" - function getQualifiedElementName(elementName) { - var qualifiedName; - switch (elementName.type) { - case jsx_syntax_1.JSXSyntax.JSXIdentifier: - var id = elementName; - qualifiedName = id.name; - break; - case jsx_syntax_1.JSXSyntax.JSXNamespacedName: - var ns = elementName; - qualifiedName = getQualifiedElementName(ns.namespace) + ':' + - getQualifiedElementName(ns.name); - break; - case jsx_syntax_1.JSXSyntax.JSXMemberExpression: - var expr = elementName; - qualifiedName = getQualifiedElementName(expr.object) + '.' + - getQualifiedElementName(expr.property); - break; - /* istanbul ignore next */ - default: - break; - } - return qualifiedName; - } - var JSXParser = (function (_super) { - __extends(JSXParser, _super); - function JSXParser(code, options, delegate) { - return _super.call(this, code, options, delegate) || this; - } - JSXParser.prototype.parsePrimaryExpression = function () { - return this.match('<') ? this.parseJSXRoot() : _super.prototype.parsePrimaryExpression.call(this); - }; - JSXParser.prototype.startJSX = function () { - // Unwind the scanner before the lookahead token. - this.scanner.index = this.startMarker.index; - this.scanner.lineNumber = this.startMarker.line; - this.scanner.lineStart = this.startMarker.index - this.startMarker.column; - }; - JSXParser.prototype.finishJSX = function () { - // Prime the next lookahead. - this.nextToken(); - }; - JSXParser.prototype.reenterJSX = function () { - this.startJSX(); - this.expectJSX('}'); - // Pop the closing '}' added from the lookahead. - if (this.config.tokens) { - this.tokens.pop(); - } - }; - JSXParser.prototype.createJSXNode = function () { - this.collectComments(); - return { - index: this.scanner.index, - line: this.scanner.lineNumber, - column: this.scanner.index - this.scanner.lineStart - }; - }; - JSXParser.prototype.createJSXChildNode = function () { - return { - index: this.scanner.index, - line: this.scanner.lineNumber, - column: this.scanner.index - this.scanner.lineStart - }; - }; - JSXParser.prototype.scanXHTMLEntity = function (quote) { - var result = '&'; - var valid = true; - var terminated = false; - var numeric = false; - var hex = false; - while (!this.scanner.eof() && valid && !terminated) { - var ch = this.scanner.source[this.scanner.index]; - if (ch === quote) { - break; - } - terminated = (ch === ';'); - result += ch; - ++this.scanner.index; - if (!terminated) { - switch (result.length) { - case 2: - // e.g. '{' - numeric = (ch === '#'); - break; - case 3: - if (numeric) { - // e.g. 'A' - hex = (ch === 'x'); - valid = hex || character_1.Character.isDecimalDigit(ch.charCodeAt(0)); - numeric = numeric && !hex; - } - break; - default: - valid = valid && !(numeric && !character_1.Character.isDecimalDigit(ch.charCodeAt(0))); - valid = valid && !(hex && !character_1.Character.isHexDigit(ch.charCodeAt(0))); - break; - } - } - } - if (valid && terminated && result.length > 2) { - // e.g. 'A' becomes just '#x41' - var str = result.substr(1, result.length - 2); - if (numeric && str.length > 1) { - result = String.fromCharCode(parseInt(str.substr(1), 10)); - } - else if (hex && str.length > 2) { - result = String.fromCharCode(parseInt('0' + str.substr(1), 16)); - } - else if (!numeric && !hex && xhtml_entities_1.XHTMLEntities[str]) { - result = xhtml_entities_1.XHTMLEntities[str]; - } - } - return result; - }; - // Scan the next JSX token. This replaces Scanner#lex when in JSX mode. - JSXParser.prototype.lexJSX = function () { - var cp = this.scanner.source.charCodeAt(this.scanner.index); - // < > / : = { } - if (cp === 60 || cp === 62 || cp === 47 || cp === 58 || cp === 61 || cp === 123 || cp === 125) { - var value = this.scanner.source[this.scanner.index++]; - return { - type: 7 /* Punctuator */, - value: value, - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: this.scanner.index - 1, - end: this.scanner.index - }; - } - // " ' - if (cp === 34 || cp === 39) { - var start = this.scanner.index; - var quote = this.scanner.source[this.scanner.index++]; - var str = ''; - while (!this.scanner.eof()) { - var ch = this.scanner.source[this.scanner.index++]; - if (ch === quote) { - break; - } - else if (ch === '&') { - str += this.scanXHTMLEntity(quote); - } - else { - str += ch; - } - } - return { - type: 8 /* StringLiteral */, - value: str, - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: start, - end: this.scanner.index - }; - } - // ... or . - if (cp === 46) { - var n1 = this.scanner.source.charCodeAt(this.scanner.index + 1); - var n2 = this.scanner.source.charCodeAt(this.scanner.index + 2); - var value = (n1 === 46 && n2 === 46) ? '...' : '.'; - var start = this.scanner.index; - this.scanner.index += value.length; - return { - type: 7 /* Punctuator */, - value: value, - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: start, - end: this.scanner.index - }; - } - // ` - if (cp === 96) { - // Only placeholder, since it will be rescanned as a real assignment expression. - return { - type: 10 /* Template */, - value: '', - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: this.scanner.index, - end: this.scanner.index - }; - } - // Identifer can not contain backslash (char code 92). - if (character_1.Character.isIdentifierStart(cp) && (cp !== 92)) { - var start = this.scanner.index; - ++this.scanner.index; - while (!this.scanner.eof()) { - var ch = this.scanner.source.charCodeAt(this.scanner.index); - if (character_1.Character.isIdentifierPart(ch) && (ch !== 92)) { - ++this.scanner.index; - } - else if (ch === 45) { - // Hyphen (char code 45) can be part of an identifier. - ++this.scanner.index; - } - else { - break; - } - } - var id = this.scanner.source.slice(start, this.scanner.index); - return { - type: 100 /* Identifier */, - value: id, - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: start, - end: this.scanner.index - }; - } - return this.scanner.lex(); - }; - JSXParser.prototype.nextJSXToken = function () { - this.collectComments(); - this.startMarker.index = this.scanner.index; - this.startMarker.line = this.scanner.lineNumber; - this.startMarker.column = this.scanner.index - this.scanner.lineStart; - var token = this.lexJSX(); - this.lastMarker.index = this.scanner.index; - this.lastMarker.line = this.scanner.lineNumber; - this.lastMarker.column = this.scanner.index - this.scanner.lineStart; - if (this.config.tokens) { - this.tokens.push(this.convertToken(token)); - } - return token; - }; - JSXParser.prototype.nextJSXText = function () { - this.startMarker.index = this.scanner.index; - this.startMarker.line = this.scanner.lineNumber; - this.startMarker.column = this.scanner.index - this.scanner.lineStart; - var start = this.scanner.index; - var text = ''; - while (!this.scanner.eof()) { - var ch = this.scanner.source[this.scanner.index]; - if (ch === '{' || ch === '<') { - break; - } - ++this.scanner.index; - text += ch; - if (character_1.Character.isLineTerminator(ch.charCodeAt(0))) { - ++this.scanner.lineNumber; - if (ch === '\r' && this.scanner.source[this.scanner.index] === '\n') { - ++this.scanner.index; - } - this.scanner.lineStart = this.scanner.index; - } - } - this.lastMarker.index = this.scanner.index; - this.lastMarker.line = this.scanner.lineNumber; - this.lastMarker.column = this.scanner.index - this.scanner.lineStart; - var token = { - type: 101 /* Text */, - value: text, - lineNumber: this.scanner.lineNumber, - lineStart: this.scanner.lineStart, - start: start, - end: this.scanner.index - }; - if ((text.length > 0) && this.config.tokens) { - this.tokens.push(this.convertToken(token)); - } - return token; - }; - JSXParser.prototype.peekJSXToken = function () { - var state = this.scanner.saveState(); - this.scanner.scanComments(); - var next = this.lexJSX(); - this.scanner.restoreState(state); - return next; - }; - // Expect the next JSX token to match the specified punctuator. - // If not, an exception will be thrown. - JSXParser.prototype.expectJSX = function (value) { - var token = this.nextJSXToken(); - if (token.type !== 7 /* Punctuator */ || token.value !== value) { - this.throwUnexpectedToken(token); - } - }; - // Return true if the next JSX token matches the specified punctuator. - JSXParser.prototype.matchJSX = function (value) { - var next = this.peekJSXToken(); - return next.type === 7 /* Punctuator */ && next.value === value; - }; - JSXParser.prototype.parseJSXIdentifier = function () { - var node = this.createJSXNode(); - var token = this.nextJSXToken(); - if (token.type !== 100 /* Identifier */) { - this.throwUnexpectedToken(token); - } - return this.finalize(node, new JSXNode.JSXIdentifier(token.value)); - }; - JSXParser.prototype.parseJSXElementName = function () { - var node = this.createJSXNode(); - var elementName = this.parseJSXIdentifier(); - if (this.matchJSX(':')) { - var namespace = elementName; - this.expectJSX(':'); - var name_1 = this.parseJSXIdentifier(); - elementName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_1)); - } - else if (this.matchJSX('.')) { - while (this.matchJSX('.')) { - var object = elementName; - this.expectJSX('.'); - var property = this.parseJSXIdentifier(); - elementName = this.finalize(node, new JSXNode.JSXMemberExpression(object, property)); - } - } - return elementName; - }; - JSXParser.prototype.parseJSXAttributeName = function () { - var node = this.createJSXNode(); - var attributeName; - var identifier = this.parseJSXIdentifier(); - if (this.matchJSX(':')) { - var namespace = identifier; - this.expectJSX(':'); - var name_2 = this.parseJSXIdentifier(); - attributeName = this.finalize(node, new JSXNode.JSXNamespacedName(namespace, name_2)); - } - else { - attributeName = identifier; - } - return attributeName; - }; - JSXParser.prototype.parseJSXStringLiteralAttribute = function () { - var node = this.createJSXNode(); - var token = this.nextJSXToken(); - if (token.type !== 8 /* StringLiteral */) { - this.throwUnexpectedToken(token); - } - var raw = this.getTokenRaw(token); - return this.finalize(node, new Node.Literal(token.value, raw)); - }; - JSXParser.prototype.parseJSXExpressionAttribute = function () { - var node = this.createJSXNode(); - this.expectJSX('{'); - this.finishJSX(); - if (this.match('}')) { - this.tolerateError('JSX attributes must only be assigned a non-empty expression'); - } - var expression = this.parseAssignmentExpression(); - this.reenterJSX(); - return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); - }; - JSXParser.prototype.parseJSXAttributeValue = function () { - return this.matchJSX('{') ? this.parseJSXExpressionAttribute() : - this.matchJSX('<') ? this.parseJSXElement() : this.parseJSXStringLiteralAttribute(); - }; - JSXParser.prototype.parseJSXNameValueAttribute = function () { - var node = this.createJSXNode(); - var name = this.parseJSXAttributeName(); - var value = null; - if (this.matchJSX('=')) { - this.expectJSX('='); - value = this.parseJSXAttributeValue(); - } - return this.finalize(node, new JSXNode.JSXAttribute(name, value)); - }; - JSXParser.prototype.parseJSXSpreadAttribute = function () { - var node = this.createJSXNode(); - this.expectJSX('{'); - this.expectJSX('...'); - this.finishJSX(); - var argument = this.parseAssignmentExpression(); - this.reenterJSX(); - return this.finalize(node, new JSXNode.JSXSpreadAttribute(argument)); - }; - JSXParser.prototype.parseJSXAttributes = function () { - var attributes = []; - while (!this.matchJSX('/') && !this.matchJSX('>')) { - var attribute = this.matchJSX('{') ? this.parseJSXSpreadAttribute() : - this.parseJSXNameValueAttribute(); - attributes.push(attribute); - } - return attributes; - }; - JSXParser.prototype.parseJSXOpeningElement = function () { - var node = this.createJSXNode(); - this.expectJSX('<'); - var name = this.parseJSXElementName(); - var attributes = this.parseJSXAttributes(); - var selfClosing = this.matchJSX('/'); - if (selfClosing) { - this.expectJSX('/'); - } - this.expectJSX('>'); - return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); - }; - JSXParser.prototype.parseJSXBoundaryElement = function () { - var node = this.createJSXNode(); - this.expectJSX('<'); - if (this.matchJSX('/')) { - this.expectJSX('/'); - var name_3 = this.parseJSXElementName(); - this.expectJSX('>'); - return this.finalize(node, new JSXNode.JSXClosingElement(name_3)); - } - var name = this.parseJSXElementName(); - var attributes = this.parseJSXAttributes(); - var selfClosing = this.matchJSX('/'); - if (selfClosing) { - this.expectJSX('/'); - } - this.expectJSX('>'); - return this.finalize(node, new JSXNode.JSXOpeningElement(name, selfClosing, attributes)); - }; - JSXParser.prototype.parseJSXEmptyExpression = function () { - var node = this.createJSXChildNode(); - this.collectComments(); - this.lastMarker.index = this.scanner.index; - this.lastMarker.line = this.scanner.lineNumber; - this.lastMarker.column = this.scanner.index - this.scanner.lineStart; - return this.finalize(node, new JSXNode.JSXEmptyExpression()); - }; - JSXParser.prototype.parseJSXExpressionContainer = function () { - var node = this.createJSXNode(); - this.expectJSX('{'); - var expression; - if (this.matchJSX('}')) { - expression = this.parseJSXEmptyExpression(); - this.expectJSX('}'); - } - else { - this.finishJSX(); - expression = this.parseAssignmentExpression(); - this.reenterJSX(); - } - return this.finalize(node, new JSXNode.JSXExpressionContainer(expression)); - }; - JSXParser.prototype.parseJSXChildren = function () { - var children = []; - while (!this.scanner.eof()) { - var node = this.createJSXChildNode(); - var token = this.nextJSXText(); - if (token.start < token.end) { - var raw = this.getTokenRaw(token); - var child = this.finalize(node, new JSXNode.JSXText(token.value, raw)); - children.push(child); - } - if (this.scanner.source[this.scanner.index] === '{') { - var container = this.parseJSXExpressionContainer(); - children.push(container); - } - else { - break; - } - } - return children; - }; - JSXParser.prototype.parseComplexJSXElement = function (el) { - var stack = []; - while (!this.scanner.eof()) { - el.children = el.children.concat(this.parseJSXChildren()); - var node = this.createJSXChildNode(); - var element = this.parseJSXBoundaryElement(); - if (element.type === jsx_syntax_1.JSXSyntax.JSXOpeningElement) { - var opening = element; - if (opening.selfClosing) { - var child = this.finalize(node, new JSXNode.JSXElement(opening, [], null)); - el.children.push(child); - } - else { - stack.push(el); - el = { node: node, opening: opening, closing: null, children: [] }; - } - } - if (element.type === jsx_syntax_1.JSXSyntax.JSXClosingElement) { - el.closing = element; - var open_1 = getQualifiedElementName(el.opening.name); - var close_1 = getQualifiedElementName(el.closing.name); - if (open_1 !== close_1) { - this.tolerateError('Expected corresponding JSX closing tag for %0', open_1); - } - if (stack.length > 0) { - var child = this.finalize(el.node, new JSXNode.JSXElement(el.opening, el.children, el.closing)); - el = stack[stack.length - 1]; - el.children.push(child); - stack.pop(); - } - else { - break; - } - } - } - return el; - }; - JSXParser.prototype.parseJSXElement = function () { - var node = this.createJSXNode(); - var opening = this.parseJSXOpeningElement(); - var children = []; - var closing = null; - if (!opening.selfClosing) { - var el = this.parseComplexJSXElement({ node: node, opening: opening, closing: closing, children: children }); - children = el.children; - closing = el.closing; - } - return this.finalize(node, new JSXNode.JSXElement(opening, children, closing)); - }; - JSXParser.prototype.parseJSXRoot = function () { - // Pop the opening '<' added from the lookahead. - if (this.config.tokens) { - this.tokens.pop(); - } - this.startJSX(); - var element = this.parseJSXElement(); - this.finishJSX(); - return element; - }; - JSXParser.prototype.isStartOfExpression = function () { - return _super.prototype.isStartOfExpression.call(this) || this.match('<'); - }; - return JSXParser; - }(parser_1.Parser)); - exports.JSXParser = JSXParser; - - -/***/ }, -/* 4 */ -/***/ function(module, exports) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - // See also tools/generate-unicode-regex.js. - var Regex = { - // Unicode v8.0.0 NonAsciiIdentifierStart: - NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/, - // Unicode v8.0.0 NonAsciiIdentifierPart: - NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/ - }; - exports.Character = { - /* tslint:disable:no-bitwise */ - fromCodePoint: function (cp) { - return (cp < 0x10000) ? String.fromCharCode(cp) : - String.fromCharCode(0xD800 + ((cp - 0x10000) >> 10)) + - String.fromCharCode(0xDC00 + ((cp - 0x10000) & 1023)); - }, - // https://tc39.github.io/ecma262/#sec-white-space - isWhiteSpace: function (cp) { - return (cp === 0x20) || (cp === 0x09) || (cp === 0x0B) || (cp === 0x0C) || (cp === 0xA0) || - (cp >= 0x1680 && [0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(cp) >= 0); - }, - // https://tc39.github.io/ecma262/#sec-line-terminators - isLineTerminator: function (cp) { - return (cp === 0x0A) || (cp === 0x0D) || (cp === 0x2028) || (cp === 0x2029); - }, - // https://tc39.github.io/ecma262/#sec-names-and-keywords - isIdentifierStart: function (cp) { - return (cp === 0x24) || (cp === 0x5F) || - (cp >= 0x41 && cp <= 0x5A) || - (cp >= 0x61 && cp <= 0x7A) || - (cp === 0x5C) || - ((cp >= 0x80) && Regex.NonAsciiIdentifierStart.test(exports.Character.fromCodePoint(cp))); - }, - isIdentifierPart: function (cp) { - return (cp === 0x24) || (cp === 0x5F) || - (cp >= 0x41 && cp <= 0x5A) || - (cp >= 0x61 && cp <= 0x7A) || - (cp >= 0x30 && cp <= 0x39) || - (cp === 0x5C) || - ((cp >= 0x80) && Regex.NonAsciiIdentifierPart.test(exports.Character.fromCodePoint(cp))); - }, - // https://tc39.github.io/ecma262/#sec-literals-numeric-literals - isDecimalDigit: function (cp) { - return (cp >= 0x30 && cp <= 0x39); // 0..9 - }, - isHexDigit: function (cp) { - return (cp >= 0x30 && cp <= 0x39) || - (cp >= 0x41 && cp <= 0x46) || - (cp >= 0x61 && cp <= 0x66); // a..f - }, - isOctalDigit: function (cp) { - return (cp >= 0x30 && cp <= 0x37); // 0..7 - } - }; - - -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var jsx_syntax_1 = __webpack_require__(6); - /* tslint:disable:max-classes-per-file */ - var JSXClosingElement = (function () { - function JSXClosingElement(name) { - this.type = jsx_syntax_1.JSXSyntax.JSXClosingElement; - this.name = name; - } - return JSXClosingElement; - }()); - exports.JSXClosingElement = JSXClosingElement; - var JSXElement = (function () { - function JSXElement(openingElement, children, closingElement) { - this.type = jsx_syntax_1.JSXSyntax.JSXElement; - this.openingElement = openingElement; - this.children = children; - this.closingElement = closingElement; - } - return JSXElement; - }()); - exports.JSXElement = JSXElement; - var JSXEmptyExpression = (function () { - function JSXEmptyExpression() { - this.type = jsx_syntax_1.JSXSyntax.JSXEmptyExpression; - } - return JSXEmptyExpression; - }()); - exports.JSXEmptyExpression = JSXEmptyExpression; - var JSXExpressionContainer = (function () { - function JSXExpressionContainer(expression) { - this.type = jsx_syntax_1.JSXSyntax.JSXExpressionContainer; - this.expression = expression; - } - return JSXExpressionContainer; - }()); - exports.JSXExpressionContainer = JSXExpressionContainer; - var JSXIdentifier = (function () { - function JSXIdentifier(name) { - this.type = jsx_syntax_1.JSXSyntax.JSXIdentifier; - this.name = name; - } - return JSXIdentifier; - }()); - exports.JSXIdentifier = JSXIdentifier; - var JSXMemberExpression = (function () { - function JSXMemberExpression(object, property) { - this.type = jsx_syntax_1.JSXSyntax.JSXMemberExpression; - this.object = object; - this.property = property; - } - return JSXMemberExpression; - }()); - exports.JSXMemberExpression = JSXMemberExpression; - var JSXAttribute = (function () { - function JSXAttribute(name, value) { - this.type = jsx_syntax_1.JSXSyntax.JSXAttribute; - this.name = name; - this.value = value; - } - return JSXAttribute; - }()); - exports.JSXAttribute = JSXAttribute; - var JSXNamespacedName = (function () { - function JSXNamespacedName(namespace, name) { - this.type = jsx_syntax_1.JSXSyntax.JSXNamespacedName; - this.namespace = namespace; - this.name = name; - } - return JSXNamespacedName; - }()); - exports.JSXNamespacedName = JSXNamespacedName; - var JSXOpeningElement = (function () { - function JSXOpeningElement(name, selfClosing, attributes) { - this.type = jsx_syntax_1.JSXSyntax.JSXOpeningElement; - this.name = name; - this.selfClosing = selfClosing; - this.attributes = attributes; - } - return JSXOpeningElement; - }()); - exports.JSXOpeningElement = JSXOpeningElement; - var JSXSpreadAttribute = (function () { - function JSXSpreadAttribute(argument) { - this.type = jsx_syntax_1.JSXSyntax.JSXSpreadAttribute; - this.argument = argument; - } - return JSXSpreadAttribute; - }()); - exports.JSXSpreadAttribute = JSXSpreadAttribute; - var JSXText = (function () { - function JSXText(value, raw) { - this.type = jsx_syntax_1.JSXSyntax.JSXText; - this.value = value; - this.raw = raw; - } - return JSXText; - }()); - exports.JSXText = JSXText; - - -/***/ }, -/* 6 */ -/***/ function(module, exports) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.JSXSyntax = { - JSXAttribute: 'JSXAttribute', - JSXClosingElement: 'JSXClosingElement', - JSXElement: 'JSXElement', - JSXEmptyExpression: 'JSXEmptyExpression', - JSXExpressionContainer: 'JSXExpressionContainer', - JSXIdentifier: 'JSXIdentifier', - JSXMemberExpression: 'JSXMemberExpression', - JSXNamespacedName: 'JSXNamespacedName', - JSXOpeningElement: 'JSXOpeningElement', - JSXSpreadAttribute: 'JSXSpreadAttribute', - JSXText: 'JSXText' - }; - - -/***/ }, -/* 7 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var syntax_1 = __webpack_require__(2); - /* tslint:disable:max-classes-per-file */ - var ArrayExpression = (function () { - function ArrayExpression(elements) { - this.type = syntax_1.Syntax.ArrayExpression; - this.elements = elements; - } - return ArrayExpression; - }()); - exports.ArrayExpression = ArrayExpression; - var ArrayPattern = (function () { - function ArrayPattern(elements) { - this.type = syntax_1.Syntax.ArrayPattern; - this.elements = elements; - } - return ArrayPattern; - }()); - exports.ArrayPattern = ArrayPattern; - var ArrowFunctionExpression = (function () { - function ArrowFunctionExpression(params, body, expression) { - this.type = syntax_1.Syntax.ArrowFunctionExpression; - this.id = null; - this.params = params; - this.body = body; - this.generator = false; - this.expression = expression; - this.async = false; - } - return ArrowFunctionExpression; - }()); - exports.ArrowFunctionExpression = ArrowFunctionExpression; - var AssignmentExpression = (function () { - function AssignmentExpression(operator, left, right) { - this.type = syntax_1.Syntax.AssignmentExpression; - this.operator = operator; - this.left = left; - this.right = right; - } - return AssignmentExpression; - }()); - exports.AssignmentExpression = AssignmentExpression; - var AssignmentPattern = (function () { - function AssignmentPattern(left, right) { - this.type = syntax_1.Syntax.AssignmentPattern; - this.left = left; - this.right = right; - } - return AssignmentPattern; - }()); - exports.AssignmentPattern = AssignmentPattern; - var AsyncArrowFunctionExpression = (function () { - function AsyncArrowFunctionExpression(params, body, expression) { - this.type = syntax_1.Syntax.ArrowFunctionExpression; - this.id = null; - this.params = params; - this.body = body; - this.generator = false; - this.expression = expression; - this.async = true; - } - return AsyncArrowFunctionExpression; - }()); - exports.AsyncArrowFunctionExpression = AsyncArrowFunctionExpression; - var AsyncFunctionDeclaration = (function () { - function AsyncFunctionDeclaration(id, params, body) { - this.type = syntax_1.Syntax.FunctionDeclaration; - this.id = id; - this.params = params; - this.body = body; - this.generator = false; - this.expression = false; - this.async = true; - } - return AsyncFunctionDeclaration; - }()); - exports.AsyncFunctionDeclaration = AsyncFunctionDeclaration; - var AsyncFunctionExpression = (function () { - function AsyncFunctionExpression(id, params, body) { - this.type = syntax_1.Syntax.FunctionExpression; - this.id = id; - this.params = params; - this.body = body; - this.generator = false; - this.expression = false; - this.async = true; - } - return AsyncFunctionExpression; - }()); - exports.AsyncFunctionExpression = AsyncFunctionExpression; - var AwaitExpression = (function () { - function AwaitExpression(argument) { - this.type = syntax_1.Syntax.AwaitExpression; - this.argument = argument; - } - return AwaitExpression; - }()); - exports.AwaitExpression = AwaitExpression; - var BinaryExpression = (function () { - function BinaryExpression(operator, left, right) { - var logical = (operator === '||' || operator === '&&'); - this.type = logical ? syntax_1.Syntax.LogicalExpression : syntax_1.Syntax.BinaryExpression; - this.operator = operator; - this.left = left; - this.right = right; - } - return BinaryExpression; - }()); - exports.BinaryExpression = BinaryExpression; - var BlockStatement = (function () { - function BlockStatement(body) { - this.type = syntax_1.Syntax.BlockStatement; - this.body = body; - } - return BlockStatement; - }()); - exports.BlockStatement = BlockStatement; - var BreakStatement = (function () { - function BreakStatement(label) { - this.type = syntax_1.Syntax.BreakStatement; - this.label = label; - } - return BreakStatement; - }()); - exports.BreakStatement = BreakStatement; - var CallExpression = (function () { - function CallExpression(callee, args) { - this.type = syntax_1.Syntax.CallExpression; - this.callee = callee; - this.arguments = args; - } - return CallExpression; - }()); - exports.CallExpression = CallExpression; - var CatchClause = (function () { - function CatchClause(param, body) { - this.type = syntax_1.Syntax.CatchClause; - this.param = param; - this.body = body; - } - return CatchClause; - }()); - exports.CatchClause = CatchClause; - var ClassBody = (function () { - function ClassBody(body) { - this.type = syntax_1.Syntax.ClassBody; - this.body = body; - } - return ClassBody; - }()); - exports.ClassBody = ClassBody; - var ClassDeclaration = (function () { - function ClassDeclaration(id, superClass, body) { - this.type = syntax_1.Syntax.ClassDeclaration; - this.id = id; - this.superClass = superClass; - this.body = body; - } - return ClassDeclaration; - }()); - exports.ClassDeclaration = ClassDeclaration; - var ClassExpression = (function () { - function ClassExpression(id, superClass, body) { - this.type = syntax_1.Syntax.ClassExpression; - this.id = id; - this.superClass = superClass; - this.body = body; - } - return ClassExpression; - }()); - exports.ClassExpression = ClassExpression; - var ComputedMemberExpression = (function () { - function ComputedMemberExpression(object, property) { - this.type = syntax_1.Syntax.MemberExpression; - this.computed = true; - this.object = object; - this.property = property; - } - return ComputedMemberExpression; - }()); - exports.ComputedMemberExpression = ComputedMemberExpression; - var ConditionalExpression = (function () { - function ConditionalExpression(test, consequent, alternate) { - this.type = syntax_1.Syntax.ConditionalExpression; - this.test = test; - this.consequent = consequent; - this.alternate = alternate; - } - return ConditionalExpression; - }()); - exports.ConditionalExpression = ConditionalExpression; - var ContinueStatement = (function () { - function ContinueStatement(label) { - this.type = syntax_1.Syntax.ContinueStatement; - this.label = label; - } - return ContinueStatement; - }()); - exports.ContinueStatement = ContinueStatement; - var DebuggerStatement = (function () { - function DebuggerStatement() { - this.type = syntax_1.Syntax.DebuggerStatement; - } - return DebuggerStatement; - }()); - exports.DebuggerStatement = DebuggerStatement; - var Directive = (function () { - function Directive(expression, directive) { - this.type = syntax_1.Syntax.ExpressionStatement; - this.expression = expression; - this.directive = directive; - } - return Directive; - }()); - exports.Directive = Directive; - var DoWhileStatement = (function () { - function DoWhileStatement(body, test) { - this.type = syntax_1.Syntax.DoWhileStatement; - this.body = body; - this.test = test; - } - return DoWhileStatement; - }()); - exports.DoWhileStatement = DoWhileStatement; - var EmptyStatement = (function () { - function EmptyStatement() { - this.type = syntax_1.Syntax.EmptyStatement; - } - return EmptyStatement; - }()); - exports.EmptyStatement = EmptyStatement; - var ExportAllDeclaration = (function () { - function ExportAllDeclaration(source) { - this.type = syntax_1.Syntax.ExportAllDeclaration; - this.source = source; - } - return ExportAllDeclaration; - }()); - exports.ExportAllDeclaration = ExportAllDeclaration; - var ExportDefaultDeclaration = (function () { - function ExportDefaultDeclaration(declaration) { - this.type = syntax_1.Syntax.ExportDefaultDeclaration; - this.declaration = declaration; - } - return ExportDefaultDeclaration; - }()); - exports.ExportDefaultDeclaration = ExportDefaultDeclaration; - var ExportNamedDeclaration = (function () { - function ExportNamedDeclaration(declaration, specifiers, source) { - this.type = syntax_1.Syntax.ExportNamedDeclaration; - this.declaration = declaration; - this.specifiers = specifiers; - this.source = source; - } - return ExportNamedDeclaration; - }()); - exports.ExportNamedDeclaration = ExportNamedDeclaration; - var ExportSpecifier = (function () { - function ExportSpecifier(local, exported) { - this.type = syntax_1.Syntax.ExportSpecifier; - this.exported = exported; - this.local = local; - } - return ExportSpecifier; - }()); - exports.ExportSpecifier = ExportSpecifier; - var ExpressionStatement = (function () { - function ExpressionStatement(expression) { - this.type = syntax_1.Syntax.ExpressionStatement; - this.expression = expression; - } - return ExpressionStatement; - }()); - exports.ExpressionStatement = ExpressionStatement; - var ForInStatement = (function () { - function ForInStatement(left, right, body) { - this.type = syntax_1.Syntax.ForInStatement; - this.left = left; - this.right = right; - this.body = body; - this.each = false; - } - return ForInStatement; - }()); - exports.ForInStatement = ForInStatement; - var ForOfStatement = (function () { - function ForOfStatement(left, right, body) { - this.type = syntax_1.Syntax.ForOfStatement; - this.left = left; - this.right = right; - this.body = body; - } - return ForOfStatement; - }()); - exports.ForOfStatement = ForOfStatement; - var ForStatement = (function () { - function ForStatement(init, test, update, body) { - this.type = syntax_1.Syntax.ForStatement; - this.init = init; - this.test = test; - this.update = update; - this.body = body; - } - return ForStatement; - }()); - exports.ForStatement = ForStatement; - var FunctionDeclaration = (function () { - function FunctionDeclaration(id, params, body, generator) { - this.type = syntax_1.Syntax.FunctionDeclaration; - this.id = id; - this.params = params; - this.body = body; - this.generator = generator; - this.expression = false; - this.async = false; - } - return FunctionDeclaration; - }()); - exports.FunctionDeclaration = FunctionDeclaration; - var FunctionExpression = (function () { - function FunctionExpression(id, params, body, generator) { - this.type = syntax_1.Syntax.FunctionExpression; - this.id = id; - this.params = params; - this.body = body; - this.generator = generator; - this.expression = false; - this.async = false; - } - return FunctionExpression; - }()); - exports.FunctionExpression = FunctionExpression; - var Identifier = (function () { - function Identifier(name) { - this.type = syntax_1.Syntax.Identifier; - this.name = name; - } - return Identifier; - }()); - exports.Identifier = Identifier; - var IfStatement = (function () { - function IfStatement(test, consequent, alternate) { - this.type = syntax_1.Syntax.IfStatement; - this.test = test; - this.consequent = consequent; - this.alternate = alternate; - } - return IfStatement; - }()); - exports.IfStatement = IfStatement; - var ImportDeclaration = (function () { - function ImportDeclaration(specifiers, source) { - this.type = syntax_1.Syntax.ImportDeclaration; - this.specifiers = specifiers; - this.source = source; - } - return ImportDeclaration; - }()); - exports.ImportDeclaration = ImportDeclaration; - var ImportDefaultSpecifier = (function () { - function ImportDefaultSpecifier(local) { - this.type = syntax_1.Syntax.ImportDefaultSpecifier; - this.local = local; - } - return ImportDefaultSpecifier; - }()); - exports.ImportDefaultSpecifier = ImportDefaultSpecifier; - var ImportNamespaceSpecifier = (function () { - function ImportNamespaceSpecifier(local) { - this.type = syntax_1.Syntax.ImportNamespaceSpecifier; - this.local = local; - } - return ImportNamespaceSpecifier; - }()); - exports.ImportNamespaceSpecifier = ImportNamespaceSpecifier; - var ImportSpecifier = (function () { - function ImportSpecifier(local, imported) { - this.type = syntax_1.Syntax.ImportSpecifier; - this.local = local; - this.imported = imported; - } - return ImportSpecifier; - }()); - exports.ImportSpecifier = ImportSpecifier; - var LabeledStatement = (function () { - function LabeledStatement(label, body) { - this.type = syntax_1.Syntax.LabeledStatement; - this.label = label; - this.body = body; - } - return LabeledStatement; - }()); - exports.LabeledStatement = LabeledStatement; - var Literal = (function () { - function Literal(value, raw) { - this.type = syntax_1.Syntax.Literal; - this.value = value; - this.raw = raw; - } - return Literal; - }()); - exports.Literal = Literal; - var MetaProperty = (function () { - function MetaProperty(meta, property) { - this.type = syntax_1.Syntax.MetaProperty; - this.meta = meta; - this.property = property; - } - return MetaProperty; - }()); - exports.MetaProperty = MetaProperty; - var MethodDefinition = (function () { - function MethodDefinition(key, computed, value, kind, isStatic) { - this.type = syntax_1.Syntax.MethodDefinition; - this.key = key; - this.computed = computed; - this.value = value; - this.kind = kind; - this.static = isStatic; - } - return MethodDefinition; - }()); - exports.MethodDefinition = MethodDefinition; - var Module = (function () { - function Module(body) { - this.type = syntax_1.Syntax.Program; - this.body = body; - this.sourceType = 'module'; - } - return Module; - }()); - exports.Module = Module; - var NewExpression = (function () { - function NewExpression(callee, args) { - this.type = syntax_1.Syntax.NewExpression; - this.callee = callee; - this.arguments = args; - } - return NewExpression; - }()); - exports.NewExpression = NewExpression; - var ObjectExpression = (function () { - function ObjectExpression(properties) { - this.type = syntax_1.Syntax.ObjectExpression; - this.properties = properties; - } - return ObjectExpression; - }()); - exports.ObjectExpression = ObjectExpression; - var ObjectPattern = (function () { - function ObjectPattern(properties) { - this.type = syntax_1.Syntax.ObjectPattern; - this.properties = properties; - } - return ObjectPattern; - }()); - exports.ObjectPattern = ObjectPattern; - var Property = (function () { - function Property(kind, key, computed, value, method, shorthand) { - this.type = syntax_1.Syntax.Property; - this.key = key; - this.computed = computed; - this.value = value; - this.kind = kind; - this.method = method; - this.shorthand = shorthand; - } - return Property; - }()); - exports.Property = Property; - var RegexLiteral = (function () { - function RegexLiteral(value, raw, pattern, flags) { - this.type = syntax_1.Syntax.Literal; - this.value = value; - this.raw = raw; - this.regex = { pattern: pattern, flags: flags }; - } - return RegexLiteral; - }()); - exports.RegexLiteral = RegexLiteral; - var RestElement = (function () { - function RestElement(argument) { - this.type = syntax_1.Syntax.RestElement; - this.argument = argument; - } - return RestElement; - }()); - exports.RestElement = RestElement; - var ReturnStatement = (function () { - function ReturnStatement(argument) { - this.type = syntax_1.Syntax.ReturnStatement; - this.argument = argument; - } - return ReturnStatement; - }()); - exports.ReturnStatement = ReturnStatement; - var Script = (function () { - function Script(body) { - this.type = syntax_1.Syntax.Program; - this.body = body; - this.sourceType = 'script'; - } - return Script; - }()); - exports.Script = Script; - var SequenceExpression = (function () { - function SequenceExpression(expressions) { - this.type = syntax_1.Syntax.SequenceExpression; - this.expressions = expressions; - } - return SequenceExpression; - }()); - exports.SequenceExpression = SequenceExpression; - var SpreadElement = (function () { - function SpreadElement(argument) { - this.type = syntax_1.Syntax.SpreadElement; - this.argument = argument; - } - return SpreadElement; - }()); - exports.SpreadElement = SpreadElement; - var StaticMemberExpression = (function () { - function StaticMemberExpression(object, property) { - this.type = syntax_1.Syntax.MemberExpression; - this.computed = false; - this.object = object; - this.property = property; - } - return StaticMemberExpression; - }()); - exports.StaticMemberExpression = StaticMemberExpression; - var Super = (function () { - function Super() { - this.type = syntax_1.Syntax.Super; - } - return Super; - }()); - exports.Super = Super; - var SwitchCase = (function () { - function SwitchCase(test, consequent) { - this.type = syntax_1.Syntax.SwitchCase; - this.test = test; - this.consequent = consequent; - } - return SwitchCase; - }()); - exports.SwitchCase = SwitchCase; - var SwitchStatement = (function () { - function SwitchStatement(discriminant, cases) { - this.type = syntax_1.Syntax.SwitchStatement; - this.discriminant = discriminant; - this.cases = cases; - } - return SwitchStatement; - }()); - exports.SwitchStatement = SwitchStatement; - var TaggedTemplateExpression = (function () { - function TaggedTemplateExpression(tag, quasi) { - this.type = syntax_1.Syntax.TaggedTemplateExpression; - this.tag = tag; - this.quasi = quasi; - } - return TaggedTemplateExpression; - }()); - exports.TaggedTemplateExpression = TaggedTemplateExpression; - var TemplateElement = (function () { - function TemplateElement(value, tail) { - this.type = syntax_1.Syntax.TemplateElement; - this.value = value; - this.tail = tail; - } - return TemplateElement; - }()); - exports.TemplateElement = TemplateElement; - var TemplateLiteral = (function () { - function TemplateLiteral(quasis, expressions) { - this.type = syntax_1.Syntax.TemplateLiteral; - this.quasis = quasis; - this.expressions = expressions; - } - return TemplateLiteral; - }()); - exports.TemplateLiteral = TemplateLiteral; - var ThisExpression = (function () { - function ThisExpression() { - this.type = syntax_1.Syntax.ThisExpression; - } - return ThisExpression; - }()); - exports.ThisExpression = ThisExpression; - var ThrowStatement = (function () { - function ThrowStatement(argument) { - this.type = syntax_1.Syntax.ThrowStatement; - this.argument = argument; - } - return ThrowStatement; - }()); - exports.ThrowStatement = ThrowStatement; - var TryStatement = (function () { - function TryStatement(block, handler, finalizer) { - this.type = syntax_1.Syntax.TryStatement; - this.block = block; - this.handler = handler; - this.finalizer = finalizer; - } - return TryStatement; - }()); - exports.TryStatement = TryStatement; - var UnaryExpression = (function () { - function UnaryExpression(operator, argument) { - this.type = syntax_1.Syntax.UnaryExpression; - this.operator = operator; - this.argument = argument; - this.prefix = true; - } - return UnaryExpression; - }()); - exports.UnaryExpression = UnaryExpression; - var UpdateExpression = (function () { - function UpdateExpression(operator, argument, prefix) { - this.type = syntax_1.Syntax.UpdateExpression; - this.operator = operator; - this.argument = argument; - this.prefix = prefix; - } - return UpdateExpression; - }()); - exports.UpdateExpression = UpdateExpression; - var VariableDeclaration = (function () { - function VariableDeclaration(declarations, kind) { - this.type = syntax_1.Syntax.VariableDeclaration; - this.declarations = declarations; - this.kind = kind; - } - return VariableDeclaration; - }()); - exports.VariableDeclaration = VariableDeclaration; - var VariableDeclarator = (function () { - function VariableDeclarator(id, init) { - this.type = syntax_1.Syntax.VariableDeclarator; - this.id = id; - this.init = init; - } - return VariableDeclarator; - }()); - exports.VariableDeclarator = VariableDeclarator; - var WhileStatement = (function () { - function WhileStatement(test, body) { - this.type = syntax_1.Syntax.WhileStatement; - this.test = test; - this.body = body; - } - return WhileStatement; - }()); - exports.WhileStatement = WhileStatement; - var WithStatement = (function () { - function WithStatement(object, body) { - this.type = syntax_1.Syntax.WithStatement; - this.object = object; - this.body = body; - } - return WithStatement; - }()); - exports.WithStatement = WithStatement; - var YieldExpression = (function () { - function YieldExpression(argument, delegate) { - this.type = syntax_1.Syntax.YieldExpression; - this.argument = argument; - this.delegate = delegate; - } - return YieldExpression; - }()); - exports.YieldExpression = YieldExpression; - - -/***/ }, -/* 8 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var assert_1 = __webpack_require__(9); - var error_handler_1 = __webpack_require__(10); - var messages_1 = __webpack_require__(11); - var Node = __webpack_require__(7); - var scanner_1 = __webpack_require__(12); - var syntax_1 = __webpack_require__(2); - var token_1 = __webpack_require__(13); - var ArrowParameterPlaceHolder = 'ArrowParameterPlaceHolder'; - var Parser = (function () { - function Parser(code, options, delegate) { - if (options === void 0) { options = {}; } - this.config = { - range: (typeof options.range === 'boolean') && options.range, - loc: (typeof options.loc === 'boolean') && options.loc, - source: null, - tokens: (typeof options.tokens === 'boolean') && options.tokens, - comment: (typeof options.comment === 'boolean') && options.comment, - tolerant: (typeof options.tolerant === 'boolean') && options.tolerant - }; - if (this.config.loc && options.source && options.source !== null) { - this.config.source = String(options.source); - } - this.delegate = delegate; - this.errorHandler = new error_handler_1.ErrorHandler(); - this.errorHandler.tolerant = this.config.tolerant; - this.scanner = new scanner_1.Scanner(code, this.errorHandler); - this.scanner.trackComment = this.config.comment; - this.operatorPrecedence = { - ')': 0, - ';': 0, - ',': 0, - '=': 0, - ']': 0, - '||': 1, - '&&': 2, - '|': 3, - '^': 4, - '&': 5, - '==': 6, - '!=': 6, - '===': 6, - '!==': 6, - '<': 7, - '>': 7, - '<=': 7, - '>=': 7, - '<<': 8, - '>>': 8, - '>>>': 8, - '+': 9, - '-': 9, - '*': 11, - '/': 11, - '%': 11 - }; - this.lookahead = { - type: 2 /* EOF */, - value: '', - lineNumber: this.scanner.lineNumber, - lineStart: 0, - start: 0, - end: 0 - }; - this.hasLineTerminator = false; - this.context = { - isModule: false, - await: false, - allowIn: true, - allowStrictDirective: true, - allowYield: true, - firstCoverInitializedNameError: null, - isAssignmentTarget: false, - isBindingElement: false, - inFunctionBody: false, - inIteration: false, - inSwitch: false, - labelSet: {}, - strict: false - }; - this.tokens = []; - this.startMarker = { - index: 0, - line: this.scanner.lineNumber, - column: 0 - }; - this.lastMarker = { - index: 0, - line: this.scanner.lineNumber, - column: 0 - }; - this.nextToken(); - this.lastMarker = { - index: this.scanner.index, - line: this.scanner.lineNumber, - column: this.scanner.index - this.scanner.lineStart - }; - } - Parser.prototype.throwError = function (messageFormat) { - var values = []; - for (var _i = 1; _i < arguments.length; _i++) { - values[_i - 1] = arguments[_i]; - } - var args = Array.prototype.slice.call(arguments, 1); - var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { - assert_1.assert(idx < args.length, 'Message reference must be in range'); - return args[idx]; - }); - var index = this.lastMarker.index; - var line = this.lastMarker.line; - var column = this.lastMarker.column + 1; - throw this.errorHandler.createError(index, line, column, msg); - }; - Parser.prototype.tolerateError = function (messageFormat) { - var values = []; - for (var _i = 1; _i < arguments.length; _i++) { - values[_i - 1] = arguments[_i]; - } - var args = Array.prototype.slice.call(arguments, 1); - var msg = messageFormat.replace(/%(\d)/g, function (whole, idx) { - assert_1.assert(idx < args.length, 'Message reference must be in range'); - return args[idx]; - }); - var index = this.lastMarker.index; - var line = this.scanner.lineNumber; - var column = this.lastMarker.column + 1; - this.errorHandler.tolerateError(index, line, column, msg); - }; - // Throw an exception because of the token. - Parser.prototype.unexpectedTokenError = function (token, message) { - var msg = message || messages_1.Messages.UnexpectedToken; - var value; - if (token) { - if (!message) { - msg = (token.type === 2 /* EOF */) ? messages_1.Messages.UnexpectedEOS : - (token.type === 3 /* Identifier */) ? messages_1.Messages.UnexpectedIdentifier : - (token.type === 6 /* NumericLiteral */) ? messages_1.Messages.UnexpectedNumber : - (token.type === 8 /* StringLiteral */) ? messages_1.Messages.UnexpectedString : - (token.type === 10 /* Template */) ? messages_1.Messages.UnexpectedTemplate : - messages_1.Messages.UnexpectedToken; - if (token.type === 4 /* Keyword */) { - if (this.scanner.isFutureReservedWord(token.value)) { - msg = messages_1.Messages.UnexpectedReserved; - } - else if (this.context.strict && this.scanner.isStrictModeReservedWord(token.value)) { - msg = messages_1.Messages.StrictReservedWord; - } - } - } - value = token.value; - } - else { - value = 'ILLEGAL'; - } - msg = msg.replace('%0', value); - if (token && typeof token.lineNumber === 'number') { - var index = token.start; - var line = token.lineNumber; - var lastMarkerLineStart = this.lastMarker.index - this.lastMarker.column; - var column = token.start - lastMarkerLineStart + 1; - return this.errorHandler.createError(index, line, column, msg); - } - else { - var index = this.lastMarker.index; - var line = this.lastMarker.line; - var column = this.lastMarker.column + 1; - return this.errorHandler.createError(index, line, column, msg); - } - }; - Parser.prototype.throwUnexpectedToken = function (token, message) { - throw this.unexpectedTokenError(token, message); - }; - Parser.prototype.tolerateUnexpectedToken = function (token, message) { - this.errorHandler.tolerate(this.unexpectedTokenError(token, message)); - }; - Parser.prototype.collectComments = function () { - if (!this.config.comment) { - this.scanner.scanComments(); - } - else { - var comments = this.scanner.scanComments(); - if (comments.length > 0 && this.delegate) { - for (var i = 0; i < comments.length; ++i) { - var e = comments[i]; - var node = void 0; - node = { - type: e.multiLine ? 'BlockComment' : 'LineComment', - value: this.scanner.source.slice(e.slice[0], e.slice[1]) - }; - if (this.config.range) { - node.range = e.range; - } - if (this.config.loc) { - node.loc = e.loc; - } - var metadata = { - start: { - line: e.loc.start.line, - column: e.loc.start.column, - offset: e.range[0] - }, - end: { - line: e.loc.end.line, - column: e.loc.end.column, - offset: e.range[1] - } - }; - this.delegate(node, metadata); - } - } - } - }; - // From internal representation to an external structure - Parser.prototype.getTokenRaw = function (token) { - return this.scanner.source.slice(token.start, token.end); - }; - Parser.prototype.convertToken = function (token) { - var t = { - type: token_1.TokenName[token.type], - value: this.getTokenRaw(token) - }; - if (this.config.range) { - t.range = [token.start, token.end]; - } - if (this.config.loc) { - t.loc = { - start: { - line: this.startMarker.line, - column: this.startMarker.column - }, - end: { - line: this.scanner.lineNumber, - column: this.scanner.index - this.scanner.lineStart - } - }; - } - if (token.type === 9 /* RegularExpression */) { - var pattern = token.pattern; - var flags = token.flags; - t.regex = { pattern: pattern, flags: flags }; - } - return t; - }; - Parser.prototype.nextToken = function () { - var token = this.lookahead; - this.lastMarker.index = this.scanner.index; - this.lastMarker.line = this.scanner.lineNumber; - this.lastMarker.column = this.scanner.index - this.scanner.lineStart; - this.collectComments(); - if (this.scanner.index !== this.startMarker.index) { - this.startMarker.index = this.scanner.index; - this.startMarker.line = this.scanner.lineNumber; - this.startMarker.column = this.scanner.index - this.scanner.lineStart; - } - var next = this.scanner.lex(); - this.hasLineTerminator = (token.lineNumber !== next.lineNumber); - if (next && this.context.strict && next.type === 3 /* Identifier */) { - if (this.scanner.isStrictModeReservedWord(next.value)) { - next.type = 4 /* Keyword */; - } - } - this.lookahead = next; - if (this.config.tokens && next.type !== 2 /* EOF */) { - this.tokens.push(this.convertToken(next)); - } - return token; - }; - Parser.prototype.nextRegexToken = function () { - this.collectComments(); - var token = this.scanner.scanRegExp(); - if (this.config.tokens) { - // Pop the previous token, '/' or '/=' - // This is added from the lookahead token. - this.tokens.pop(); - this.tokens.push(this.convertToken(token)); - } - // Prime the next lookahead. - this.lookahead = token; - this.nextToken(); - return token; - }; - Parser.prototype.createNode = function () { - return { - index: this.startMarker.index, - line: this.startMarker.line, - column: this.startMarker.column - }; - }; - Parser.prototype.startNode = function (token, lastLineStart) { - if (lastLineStart === void 0) { lastLineStart = 0; } - var column = token.start - token.lineStart; - var line = token.lineNumber; - if (column < 0) { - column += lastLineStart; - line--; - } - return { - index: token.start, - line: line, - column: column - }; - }; - Parser.prototype.finalize = function (marker, node) { - if (this.config.range) { - node.range = [marker.index, this.lastMarker.index]; - } - if (this.config.loc) { - node.loc = { - start: { - line: marker.line, - column: marker.column, - }, - end: { - line: this.lastMarker.line, - column: this.lastMarker.column - } - }; - if (this.config.source) { - node.loc.source = this.config.source; - } - } - if (this.delegate) { - var metadata = { - start: { - line: marker.line, - column: marker.column, - offset: marker.index - }, - end: { - line: this.lastMarker.line, - column: this.lastMarker.column, - offset: this.lastMarker.index - } - }; - this.delegate(node, metadata); - } - return node; - }; - // Expect the next token to match the specified punctuator. - // If not, an exception will be thrown. - Parser.prototype.expect = function (value) { - var token = this.nextToken(); - if (token.type !== 7 /* Punctuator */ || token.value !== value) { - this.throwUnexpectedToken(token); - } - }; - // Quietly expect a comma when in tolerant mode, otherwise delegates to expect(). - Parser.prototype.expectCommaSeparator = function () { - if (this.config.tolerant) { - var token = this.lookahead; - if (token.type === 7 /* Punctuator */ && token.value === ',') { - this.nextToken(); - } - else if (token.type === 7 /* Punctuator */ && token.value === ';') { - this.nextToken(); - this.tolerateUnexpectedToken(token); - } - else { - this.tolerateUnexpectedToken(token, messages_1.Messages.UnexpectedToken); - } - } - else { - this.expect(','); - } - }; - // Expect the next token to match the specified keyword. - // If not, an exception will be thrown. - Parser.prototype.expectKeyword = function (keyword) { - var token = this.nextToken(); - if (token.type !== 4 /* Keyword */ || token.value !== keyword) { - this.throwUnexpectedToken(token); - } - }; - // Return true if the next token matches the specified punctuator. - Parser.prototype.match = function (value) { - return this.lookahead.type === 7 /* Punctuator */ && this.lookahead.value === value; - }; - // Return true if the next token matches the specified keyword - Parser.prototype.matchKeyword = function (keyword) { - return this.lookahead.type === 4 /* Keyword */ && this.lookahead.value === keyword; - }; - // Return true if the next token matches the specified contextual keyword - // (where an identifier is sometimes a keyword depending on the context) - Parser.prototype.matchContextualKeyword = function (keyword) { - return this.lookahead.type === 3 /* Identifier */ && this.lookahead.value === keyword; - }; - // Return true if the next token is an assignment operator - Parser.prototype.matchAssign = function () { - if (this.lookahead.type !== 7 /* Punctuator */) { - return false; - } - var op = this.lookahead.value; - return op === '=' || - op === '*=' || - op === '**=' || - op === '/=' || - op === '%=' || - op === '+=' || - op === '-=' || - op === '<<=' || - op === '>>=' || - op === '>>>=' || - op === '&=' || - op === '^=' || - op === '|='; - }; - // Cover grammar support. - // - // When an assignment expression position starts with an left parenthesis, the determination of the type - // of the syntax is to be deferred arbitrarily long until the end of the parentheses pair (plus a lookahead) - // or the first comma. This situation also defers the determination of all the expressions nested in the pair. - // - // There are three productions that can be parsed in a parentheses pair that needs to be determined - // after the outermost pair is closed. They are: - // - // 1. AssignmentExpression - // 2. BindingElements - // 3. AssignmentTargets - // - // In order to avoid exponential backtracking, we use two flags to denote if the production can be - // binding element or assignment target. - // - // The three productions have the relationship: - // - // BindingElements ⊆ AssignmentTargets ⊆ AssignmentExpression - // - // with a single exception that CoverInitializedName when used directly in an Expression, generates - // an early error. Therefore, we need the third state, firstCoverInitializedNameError, to track the - // first usage of CoverInitializedName and report it when we reached the end of the parentheses pair. - // - // isolateCoverGrammar function runs the given parser function with a new cover grammar context, and it does not - // effect the current flags. This means the production the parser parses is only used as an expression. Therefore - // the CoverInitializedName check is conducted. - // - // inheritCoverGrammar function runs the given parse function with a new cover grammar context, and it propagates - // the flags outside of the parser. This means the production the parser parses is used as a part of a potential - // pattern. The CoverInitializedName check is deferred. - Parser.prototype.isolateCoverGrammar = function (parseFunction) { - var previousIsBindingElement = this.context.isBindingElement; - var previousIsAssignmentTarget = this.context.isAssignmentTarget; - var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; - this.context.isBindingElement = true; - this.context.isAssignmentTarget = true; - this.context.firstCoverInitializedNameError = null; - var result = parseFunction.call(this); - if (this.context.firstCoverInitializedNameError !== null) { - this.throwUnexpectedToken(this.context.firstCoverInitializedNameError); - } - this.context.isBindingElement = previousIsBindingElement; - this.context.isAssignmentTarget = previousIsAssignmentTarget; - this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError; - return result; - }; - Parser.prototype.inheritCoverGrammar = function (parseFunction) { - var previousIsBindingElement = this.context.isBindingElement; - var previousIsAssignmentTarget = this.context.isAssignmentTarget; - var previousFirstCoverInitializedNameError = this.context.firstCoverInitializedNameError; - this.context.isBindingElement = true; - this.context.isAssignmentTarget = true; - this.context.firstCoverInitializedNameError = null; - var result = parseFunction.call(this); - this.context.isBindingElement = this.context.isBindingElement && previousIsBindingElement; - this.context.isAssignmentTarget = this.context.isAssignmentTarget && previousIsAssignmentTarget; - this.context.firstCoverInitializedNameError = previousFirstCoverInitializedNameError || this.context.firstCoverInitializedNameError; - return result; - }; - Parser.prototype.consumeSemicolon = function () { - if (this.match(';')) { - this.nextToken(); - } - else if (!this.hasLineTerminator) { - if (this.lookahead.type !== 2 /* EOF */ && !this.match('}')) { - this.throwUnexpectedToken(this.lookahead); - } - this.lastMarker.index = this.startMarker.index; - this.lastMarker.line = this.startMarker.line; - this.lastMarker.column = this.startMarker.column; - } - }; - // https://tc39.github.io/ecma262/#sec-primary-expression - Parser.prototype.parsePrimaryExpression = function () { - var node = this.createNode(); - var expr; - var token, raw; - switch (this.lookahead.type) { - case 3 /* Identifier */: - if ((this.context.isModule || this.context.await) && this.lookahead.value === 'await') { - this.tolerateUnexpectedToken(this.lookahead); - } - expr = this.matchAsyncFunction() ? this.parseFunctionExpression() : this.finalize(node, new Node.Identifier(this.nextToken().value)); - break; - case 6 /* NumericLiteral */: - case 8 /* StringLiteral */: - if (this.context.strict && this.lookahead.octal) { - this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.StrictOctalLiteral); - } - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - token = this.nextToken(); - raw = this.getTokenRaw(token); - expr = this.finalize(node, new Node.Literal(token.value, raw)); - break; - case 1 /* BooleanLiteral */: - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - token = this.nextToken(); - raw = this.getTokenRaw(token); - expr = this.finalize(node, new Node.Literal(token.value === 'true', raw)); - break; - case 5 /* NullLiteral */: - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - token = this.nextToken(); - raw = this.getTokenRaw(token); - expr = this.finalize(node, new Node.Literal(null, raw)); - break; - case 10 /* Template */: - expr = this.parseTemplateLiteral(); - break; - case 7 /* Punctuator */: - switch (this.lookahead.value) { - case '(': - this.context.isBindingElement = false; - expr = this.inheritCoverGrammar(this.parseGroupExpression); - break; - case '[': - expr = this.inheritCoverGrammar(this.parseArrayInitializer); - break; - case '{': - expr = this.inheritCoverGrammar(this.parseObjectInitializer); - break; - case '/': - case '/=': - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - this.scanner.index = this.startMarker.index; - token = this.nextRegexToken(); - raw = this.getTokenRaw(token); - expr = this.finalize(node, new Node.RegexLiteral(token.regex, raw, token.pattern, token.flags)); - break; - default: - expr = this.throwUnexpectedToken(this.nextToken()); - } - break; - case 4 /* Keyword */: - if (!this.context.strict && this.context.allowYield && this.matchKeyword('yield')) { - expr = this.parseIdentifierName(); - } - else if (!this.context.strict && this.matchKeyword('let')) { - expr = this.finalize(node, new Node.Identifier(this.nextToken().value)); - } - else { - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - if (this.matchKeyword('function')) { - expr = this.parseFunctionExpression(); - } - else if (this.matchKeyword('this')) { - this.nextToken(); - expr = this.finalize(node, new Node.ThisExpression()); - } - else if (this.matchKeyword('class')) { - expr = this.parseClassExpression(); - } - else { - expr = this.throwUnexpectedToken(this.nextToken()); - } - } - break; - default: - expr = this.throwUnexpectedToken(this.nextToken()); - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-array-initializer - Parser.prototype.parseSpreadElement = function () { - var node = this.createNode(); - this.expect('...'); - var arg = this.inheritCoverGrammar(this.parseAssignmentExpression); - return this.finalize(node, new Node.SpreadElement(arg)); - }; - Parser.prototype.parseArrayInitializer = function () { - var node = this.createNode(); - var elements = []; - this.expect('['); - while (!this.match(']')) { - if (this.match(',')) { - this.nextToken(); - elements.push(null); - } - else if (this.match('...')) { - var element = this.parseSpreadElement(); - if (!this.match(']')) { - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - this.expect(','); - } - elements.push(element); - } - else { - elements.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); - if (!this.match(']')) { - this.expect(','); - } - } - } - this.expect(']'); - return this.finalize(node, new Node.ArrayExpression(elements)); - }; - // https://tc39.github.io/ecma262/#sec-object-initializer - Parser.prototype.parsePropertyMethod = function (params) { - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - var previousStrict = this.context.strict; - var previousAllowStrictDirective = this.context.allowStrictDirective; - this.context.allowStrictDirective = params.simple; - var body = this.isolateCoverGrammar(this.parseFunctionSourceElements); - if (this.context.strict && params.firstRestricted) { - this.tolerateUnexpectedToken(params.firstRestricted, params.message); - } - if (this.context.strict && params.stricted) { - this.tolerateUnexpectedToken(params.stricted, params.message); - } - this.context.strict = previousStrict; - this.context.allowStrictDirective = previousAllowStrictDirective; - return body; - }; - Parser.prototype.parsePropertyMethodFunction = function () { - var isGenerator = false; - var node = this.createNode(); - var previousAllowYield = this.context.allowYield; - this.context.allowYield = true; - var params = this.parseFormalParameters(); - var method = this.parsePropertyMethod(params); - this.context.allowYield = previousAllowYield; - return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); - }; - Parser.prototype.parsePropertyMethodAsyncFunction = function () { - var node = this.createNode(); - var previousAllowYield = this.context.allowYield; - var previousAwait = this.context.await; - this.context.allowYield = false; - this.context.await = true; - var params = this.parseFormalParameters(); - var method = this.parsePropertyMethod(params); - this.context.allowYield = previousAllowYield; - this.context.await = previousAwait; - return this.finalize(node, new Node.AsyncFunctionExpression(null, params.params, method)); - }; - Parser.prototype.parseObjectPropertyKey = function () { - var node = this.createNode(); - var token = this.nextToken(); - var key; - switch (token.type) { - case 8 /* StringLiteral */: - case 6 /* NumericLiteral */: - if (this.context.strict && token.octal) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictOctalLiteral); - } - var raw = this.getTokenRaw(token); - key = this.finalize(node, new Node.Literal(token.value, raw)); - break; - case 3 /* Identifier */: - case 1 /* BooleanLiteral */: - case 5 /* NullLiteral */: - case 4 /* Keyword */: - key = this.finalize(node, new Node.Identifier(token.value)); - break; - case 7 /* Punctuator */: - if (token.value === '[') { - key = this.isolateCoverGrammar(this.parseAssignmentExpression); - this.expect(']'); - } - else { - key = this.throwUnexpectedToken(token); - } - break; - default: - key = this.throwUnexpectedToken(token); - } - return key; - }; - Parser.prototype.isPropertyKey = function (key, value) { - return (key.type === syntax_1.Syntax.Identifier && key.name === value) || - (key.type === syntax_1.Syntax.Literal && key.value === value); - }; - Parser.prototype.parseObjectProperty = function (hasProto) { - var node = this.createNode(); - var token = this.lookahead; - var kind; - var key = null; - var value = null; - var computed = false; - var method = false; - var shorthand = false; - var isAsync = false; - if (token.type === 3 /* Identifier */) { - var id = token.value; - this.nextToken(); - computed = this.match('['); - isAsync = !this.hasLineTerminator && (id === 'async') && - !this.match(':') && !this.match('(') && !this.match('*') && !this.match(','); - key = isAsync ? this.parseObjectPropertyKey() : this.finalize(node, new Node.Identifier(id)); - } - else if (this.match('*')) { - this.nextToken(); - } - else { - computed = this.match('['); - key = this.parseObjectPropertyKey(); - } - var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); - if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'get' && lookaheadPropertyKey) { - kind = 'get'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - this.context.allowYield = false; - value = this.parseGetterMethod(); - } - else if (token.type === 3 /* Identifier */ && !isAsync && token.value === 'set' && lookaheadPropertyKey) { - kind = 'set'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - value = this.parseSetterMethod(); - } - else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { - kind = 'init'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - value = this.parseGeneratorMethod(); - method = true; - } - else { - if (!key) { - this.throwUnexpectedToken(this.lookahead); - } - kind = 'init'; - if (this.match(':') && !isAsync) { - if (!computed && this.isPropertyKey(key, '__proto__')) { - if (hasProto.value) { - this.tolerateError(messages_1.Messages.DuplicateProtoProperty); - } - hasProto.value = true; - } - this.nextToken(); - value = this.inheritCoverGrammar(this.parseAssignmentExpression); - } - else if (this.match('(')) { - value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); - method = true; - } - else if (token.type === 3 /* Identifier */) { - var id = this.finalize(node, new Node.Identifier(token.value)); - if (this.match('=')) { - this.context.firstCoverInitializedNameError = this.lookahead; - this.nextToken(); - shorthand = true; - var init = this.isolateCoverGrammar(this.parseAssignmentExpression); - value = this.finalize(node, new Node.AssignmentPattern(id, init)); - } - else { - shorthand = true; - value = id; - } - } - else { - this.throwUnexpectedToken(this.nextToken()); - } - } - return this.finalize(node, new Node.Property(kind, key, computed, value, method, shorthand)); - }; - Parser.prototype.parseObjectInitializer = function () { - var node = this.createNode(); - this.expect('{'); - var properties = []; - var hasProto = { value: false }; - while (!this.match('}')) { - properties.push(this.parseObjectProperty(hasProto)); - if (!this.match('}')) { - this.expectCommaSeparator(); - } - } - this.expect('}'); - return this.finalize(node, new Node.ObjectExpression(properties)); - }; - // https://tc39.github.io/ecma262/#sec-template-literals - Parser.prototype.parseTemplateHead = function () { - assert_1.assert(this.lookahead.head, 'Template literal must start with a template head'); - var node = this.createNode(); - var token = this.nextToken(); - var raw = token.value; - var cooked = token.cooked; - return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); - }; - Parser.prototype.parseTemplateElement = function () { - if (this.lookahead.type !== 10 /* Template */) { - this.throwUnexpectedToken(); - } - var node = this.createNode(); - var token = this.nextToken(); - var raw = token.value; - var cooked = token.cooked; - return this.finalize(node, new Node.TemplateElement({ raw: raw, cooked: cooked }, token.tail)); - }; - Parser.prototype.parseTemplateLiteral = function () { - var node = this.createNode(); - var expressions = []; - var quasis = []; - var quasi = this.parseTemplateHead(); - quasis.push(quasi); - while (!quasi.tail) { - expressions.push(this.parseExpression()); - quasi = this.parseTemplateElement(); - quasis.push(quasi); - } - return this.finalize(node, new Node.TemplateLiteral(quasis, expressions)); - }; - // https://tc39.github.io/ecma262/#sec-grouping-operator - Parser.prototype.reinterpretExpressionAsPattern = function (expr) { - switch (expr.type) { - case syntax_1.Syntax.Identifier: - case syntax_1.Syntax.MemberExpression: - case syntax_1.Syntax.RestElement: - case syntax_1.Syntax.AssignmentPattern: - break; - case syntax_1.Syntax.SpreadElement: - expr.type = syntax_1.Syntax.RestElement; - this.reinterpretExpressionAsPattern(expr.argument); - break; - case syntax_1.Syntax.ArrayExpression: - expr.type = syntax_1.Syntax.ArrayPattern; - for (var i = 0; i < expr.elements.length; i++) { - if (expr.elements[i] !== null) { - this.reinterpretExpressionAsPattern(expr.elements[i]); - } - } - break; - case syntax_1.Syntax.ObjectExpression: - expr.type = syntax_1.Syntax.ObjectPattern; - for (var i = 0; i < expr.properties.length; i++) { - this.reinterpretExpressionAsPattern(expr.properties[i].value); - } - break; - case syntax_1.Syntax.AssignmentExpression: - expr.type = syntax_1.Syntax.AssignmentPattern; - delete expr.operator; - this.reinterpretExpressionAsPattern(expr.left); - break; - default: - // Allow other node type for tolerant parsing. - break; - } - }; - Parser.prototype.parseGroupExpression = function () { - var expr; - this.expect('('); - if (this.match(')')) { - this.nextToken(); - if (!this.match('=>')) { - this.expect('=>'); - } - expr = { - type: ArrowParameterPlaceHolder, - params: [], - async: false - }; - } - else { - var startToken = this.lookahead; - var params = []; - if (this.match('...')) { - expr = this.parseRestElement(params); - this.expect(')'); - if (!this.match('=>')) { - this.expect('=>'); - } - expr = { - type: ArrowParameterPlaceHolder, - params: [expr], - async: false - }; - } - else { - var arrow = false; - this.context.isBindingElement = true; - expr = this.inheritCoverGrammar(this.parseAssignmentExpression); - if (this.match(',')) { - var expressions = []; - this.context.isAssignmentTarget = false; - expressions.push(expr); - while (this.lookahead.type !== 2 /* EOF */) { - if (!this.match(',')) { - break; - } - this.nextToken(); - if (this.match(')')) { - this.nextToken(); - for (var i = 0; i < expressions.length; i++) { - this.reinterpretExpressionAsPattern(expressions[i]); - } - arrow = true; - expr = { - type: ArrowParameterPlaceHolder, - params: expressions, - async: false - }; - } - else if (this.match('...')) { - if (!this.context.isBindingElement) { - this.throwUnexpectedToken(this.lookahead); - } - expressions.push(this.parseRestElement(params)); - this.expect(')'); - if (!this.match('=>')) { - this.expect('=>'); - } - this.context.isBindingElement = false; - for (var i = 0; i < expressions.length; i++) { - this.reinterpretExpressionAsPattern(expressions[i]); - } - arrow = true; - expr = { - type: ArrowParameterPlaceHolder, - params: expressions, - async: false - }; - } - else { - expressions.push(this.inheritCoverGrammar(this.parseAssignmentExpression)); - } - if (arrow) { - break; - } - } - if (!arrow) { - expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); - } - } - if (!arrow) { - this.expect(')'); - if (this.match('=>')) { - if (expr.type === syntax_1.Syntax.Identifier && expr.name === 'yield') { - arrow = true; - expr = { - type: ArrowParameterPlaceHolder, - params: [expr], - async: false - }; - } - if (!arrow) { - if (!this.context.isBindingElement) { - this.throwUnexpectedToken(this.lookahead); - } - if (expr.type === syntax_1.Syntax.SequenceExpression) { - for (var i = 0; i < expr.expressions.length; i++) { - this.reinterpretExpressionAsPattern(expr.expressions[i]); - } - } - else { - this.reinterpretExpressionAsPattern(expr); - } - var parameters = (expr.type === syntax_1.Syntax.SequenceExpression ? expr.expressions : [expr]); - expr = { - type: ArrowParameterPlaceHolder, - params: parameters, - async: false - }; - } - } - this.context.isBindingElement = false; - } - } - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-left-hand-side-expressions - Parser.prototype.parseArguments = function () { - this.expect('('); - var args = []; - if (!this.match(')')) { - while (true) { - var expr = this.match('...') ? this.parseSpreadElement() : - this.isolateCoverGrammar(this.parseAssignmentExpression); - args.push(expr); - if (this.match(')')) { - break; - } - this.expectCommaSeparator(); - if (this.match(')')) { - break; - } - } - } - this.expect(')'); - return args; - }; - Parser.prototype.isIdentifierName = function (token) { - return token.type === 3 /* Identifier */ || - token.type === 4 /* Keyword */ || - token.type === 1 /* BooleanLiteral */ || - token.type === 5 /* NullLiteral */; - }; - Parser.prototype.parseIdentifierName = function () { - var node = this.createNode(); - var token = this.nextToken(); - if (!this.isIdentifierName(token)) { - this.throwUnexpectedToken(token); - } - return this.finalize(node, new Node.Identifier(token.value)); - }; - Parser.prototype.parseNewExpression = function () { - var node = this.createNode(); - var id = this.parseIdentifierName(); - assert_1.assert(id.name === 'new', 'New expression must start with `new`'); - var expr; - if (this.match('.')) { - this.nextToken(); - if (this.lookahead.type === 3 /* Identifier */ && this.context.inFunctionBody && this.lookahead.value === 'target') { - var property = this.parseIdentifierName(); - expr = new Node.MetaProperty(id, property); - } - else { - this.throwUnexpectedToken(this.lookahead); - } - } - else { - var callee = this.isolateCoverGrammar(this.parseLeftHandSideExpression); - var args = this.match('(') ? this.parseArguments() : []; - expr = new Node.NewExpression(callee, args); - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - } - return this.finalize(node, expr); - }; - Parser.prototype.parseAsyncArgument = function () { - var arg = this.parseAssignmentExpression(); - this.context.firstCoverInitializedNameError = null; - return arg; - }; - Parser.prototype.parseAsyncArguments = function () { - this.expect('('); - var args = []; - if (!this.match(')')) { - while (true) { - var expr = this.match('...') ? this.parseSpreadElement() : - this.isolateCoverGrammar(this.parseAsyncArgument); - args.push(expr); - if (this.match(')')) { - break; - } - this.expectCommaSeparator(); - if (this.match(')')) { - break; - } - } - } - this.expect(')'); - return args; - }; - Parser.prototype.parseLeftHandSideExpressionAllowCall = function () { - var startToken = this.lookahead; - var maybeAsync = this.matchContextualKeyword('async'); - var previousAllowIn = this.context.allowIn; - this.context.allowIn = true; - var expr; - if (this.matchKeyword('super') && this.context.inFunctionBody) { - expr = this.createNode(); - this.nextToken(); - expr = this.finalize(expr, new Node.Super()); - if (!this.match('(') && !this.match('.') && !this.match('[')) { - this.throwUnexpectedToken(this.lookahead); - } - } - else { - expr = this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); - } - while (true) { - if (this.match('.')) { - this.context.isBindingElement = false; - this.context.isAssignmentTarget = true; - this.expect('.'); - var property = this.parseIdentifierName(); - expr = this.finalize(this.startNode(startToken), new Node.StaticMemberExpression(expr, property)); - } - else if (this.match('(')) { - var asyncArrow = maybeAsync && (startToken.lineNumber === this.lookahead.lineNumber); - this.context.isBindingElement = false; - this.context.isAssignmentTarget = false; - var args = asyncArrow ? this.parseAsyncArguments() : this.parseArguments(); - expr = this.finalize(this.startNode(startToken), new Node.CallExpression(expr, args)); - if (asyncArrow && this.match('=>')) { - for (var i = 0; i < args.length; ++i) { - this.reinterpretExpressionAsPattern(args[i]); - } - expr = { - type: ArrowParameterPlaceHolder, - params: args, - async: true - }; - } - } - else if (this.match('[')) { - this.context.isBindingElement = false; - this.context.isAssignmentTarget = true; - this.expect('['); - var property = this.isolateCoverGrammar(this.parseExpression); - this.expect(']'); - expr = this.finalize(this.startNode(startToken), new Node.ComputedMemberExpression(expr, property)); - } - else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { - var quasi = this.parseTemplateLiteral(); - expr = this.finalize(this.startNode(startToken), new Node.TaggedTemplateExpression(expr, quasi)); - } - else { - break; - } - } - this.context.allowIn = previousAllowIn; - return expr; - }; - Parser.prototype.parseSuper = function () { - var node = this.createNode(); - this.expectKeyword('super'); - if (!this.match('[') && !this.match('.')) { - this.throwUnexpectedToken(this.lookahead); - } - return this.finalize(node, new Node.Super()); - }; - Parser.prototype.parseLeftHandSideExpression = function () { - assert_1.assert(this.context.allowIn, 'callee of new expression always allow in keyword.'); - var node = this.startNode(this.lookahead); - var expr = (this.matchKeyword('super') && this.context.inFunctionBody) ? this.parseSuper() : - this.inheritCoverGrammar(this.matchKeyword('new') ? this.parseNewExpression : this.parsePrimaryExpression); - while (true) { - if (this.match('[')) { - this.context.isBindingElement = false; - this.context.isAssignmentTarget = true; - this.expect('['); - var property = this.isolateCoverGrammar(this.parseExpression); - this.expect(']'); - expr = this.finalize(node, new Node.ComputedMemberExpression(expr, property)); - } - else if (this.match('.')) { - this.context.isBindingElement = false; - this.context.isAssignmentTarget = true; - this.expect('.'); - var property = this.parseIdentifierName(); - expr = this.finalize(node, new Node.StaticMemberExpression(expr, property)); - } - else if (this.lookahead.type === 10 /* Template */ && this.lookahead.head) { - var quasi = this.parseTemplateLiteral(); - expr = this.finalize(node, new Node.TaggedTemplateExpression(expr, quasi)); - } - else { - break; - } - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-update-expressions - Parser.prototype.parseUpdateExpression = function () { - var expr; - var startToken = this.lookahead; - if (this.match('++') || this.match('--')) { - var node = this.startNode(startToken); - var token = this.nextToken(); - expr = this.inheritCoverGrammar(this.parseUnaryExpression); - if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { - this.tolerateError(messages_1.Messages.StrictLHSPrefix); - } - if (!this.context.isAssignmentTarget) { - this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); - } - var prefix = true; - expr = this.finalize(node, new Node.UpdateExpression(token.value, expr, prefix)); - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - } - else { - expr = this.inheritCoverGrammar(this.parseLeftHandSideExpressionAllowCall); - if (!this.hasLineTerminator && this.lookahead.type === 7 /* Punctuator */) { - if (this.match('++') || this.match('--')) { - if (this.context.strict && expr.type === syntax_1.Syntax.Identifier && this.scanner.isRestrictedWord(expr.name)) { - this.tolerateError(messages_1.Messages.StrictLHSPostfix); - } - if (!this.context.isAssignmentTarget) { - this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); - } - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - var operator = this.nextToken().value; - var prefix = false; - expr = this.finalize(this.startNode(startToken), new Node.UpdateExpression(operator, expr, prefix)); - } - } - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-unary-operators - Parser.prototype.parseAwaitExpression = function () { - var node = this.createNode(); - this.nextToken(); - var argument = this.parseUnaryExpression(); - return this.finalize(node, new Node.AwaitExpression(argument)); - }; - Parser.prototype.parseUnaryExpression = function () { - var expr; - if (this.match('+') || this.match('-') || this.match('~') || this.match('!') || - this.matchKeyword('delete') || this.matchKeyword('void') || this.matchKeyword('typeof')) { - var node = this.startNode(this.lookahead); - var token = this.nextToken(); - expr = this.inheritCoverGrammar(this.parseUnaryExpression); - expr = this.finalize(node, new Node.UnaryExpression(token.value, expr)); - if (this.context.strict && expr.operator === 'delete' && expr.argument.type === syntax_1.Syntax.Identifier) { - this.tolerateError(messages_1.Messages.StrictDelete); - } - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - } - else if (this.context.await && this.matchContextualKeyword('await')) { - expr = this.parseAwaitExpression(); - } - else { - expr = this.parseUpdateExpression(); - } - return expr; - }; - Parser.prototype.parseExponentiationExpression = function () { - var startToken = this.lookahead; - var expr = this.inheritCoverGrammar(this.parseUnaryExpression); - if (expr.type !== syntax_1.Syntax.UnaryExpression && this.match('**')) { - this.nextToken(); - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - var left = expr; - var right = this.isolateCoverGrammar(this.parseExponentiationExpression); - expr = this.finalize(this.startNode(startToken), new Node.BinaryExpression('**', left, right)); - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-exp-operator - // https://tc39.github.io/ecma262/#sec-multiplicative-operators - // https://tc39.github.io/ecma262/#sec-additive-operators - // https://tc39.github.io/ecma262/#sec-bitwise-shift-operators - // https://tc39.github.io/ecma262/#sec-relational-operators - // https://tc39.github.io/ecma262/#sec-equality-operators - // https://tc39.github.io/ecma262/#sec-binary-bitwise-operators - // https://tc39.github.io/ecma262/#sec-binary-logical-operators - Parser.prototype.binaryPrecedence = function (token) { - var op = token.value; - var precedence; - if (token.type === 7 /* Punctuator */) { - precedence = this.operatorPrecedence[op] || 0; - } - else if (token.type === 4 /* Keyword */) { - precedence = (op === 'instanceof' || (this.context.allowIn && op === 'in')) ? 7 : 0; - } - else { - precedence = 0; - } - return precedence; - }; - Parser.prototype.parseBinaryExpression = function () { - var startToken = this.lookahead; - var expr = this.inheritCoverGrammar(this.parseExponentiationExpression); - var token = this.lookahead; - var prec = this.binaryPrecedence(token); - if (prec > 0) { - this.nextToken(); - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - var markers = [startToken, this.lookahead]; - var left = expr; - var right = this.isolateCoverGrammar(this.parseExponentiationExpression); - var stack = [left, token.value, right]; - var precedences = [prec]; - while (true) { - prec = this.binaryPrecedence(this.lookahead); - if (prec <= 0) { - break; - } - // Reduce: make a binary expression from the three topmost entries. - while ((stack.length > 2) && (prec <= precedences[precedences.length - 1])) { - right = stack.pop(); - var operator = stack.pop(); - precedences.pop(); - left = stack.pop(); - markers.pop(); - var node = this.startNode(markers[markers.length - 1]); - stack.push(this.finalize(node, new Node.BinaryExpression(operator, left, right))); - } - // Shift. - stack.push(this.nextToken().value); - precedences.push(prec); - markers.push(this.lookahead); - stack.push(this.isolateCoverGrammar(this.parseExponentiationExpression)); - } - // Final reduce to clean-up the stack. - var i = stack.length - 1; - expr = stack[i]; - var lastMarker = markers.pop(); - while (i > 1) { - var marker = markers.pop(); - var lastLineStart = lastMarker && lastMarker.lineStart; - var node = this.startNode(marker, lastLineStart); - var operator = stack[i - 1]; - expr = this.finalize(node, new Node.BinaryExpression(operator, stack[i - 2], expr)); - i -= 2; - lastMarker = marker; - } - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-conditional-operator - Parser.prototype.parseConditionalExpression = function () { - var startToken = this.lookahead; - var expr = this.inheritCoverGrammar(this.parseBinaryExpression); - if (this.match('?')) { - this.nextToken(); - var previousAllowIn = this.context.allowIn; - this.context.allowIn = true; - var consequent = this.isolateCoverGrammar(this.parseAssignmentExpression); - this.context.allowIn = previousAllowIn; - this.expect(':'); - var alternate = this.isolateCoverGrammar(this.parseAssignmentExpression); - expr = this.finalize(this.startNode(startToken), new Node.ConditionalExpression(expr, consequent, alternate)); - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-assignment-operators - Parser.prototype.checkPatternParam = function (options, param) { - switch (param.type) { - case syntax_1.Syntax.Identifier: - this.validateParam(options, param, param.name); - break; - case syntax_1.Syntax.RestElement: - this.checkPatternParam(options, param.argument); - break; - case syntax_1.Syntax.AssignmentPattern: - this.checkPatternParam(options, param.left); - break; - case syntax_1.Syntax.ArrayPattern: - for (var i = 0; i < param.elements.length; i++) { - if (param.elements[i] !== null) { - this.checkPatternParam(options, param.elements[i]); - } - } - break; - case syntax_1.Syntax.ObjectPattern: - for (var i = 0; i < param.properties.length; i++) { - this.checkPatternParam(options, param.properties[i].value); - } - break; - default: - break; - } - options.simple = options.simple && (param instanceof Node.Identifier); - }; - Parser.prototype.reinterpretAsCoverFormalsList = function (expr) { - var params = [expr]; - var options; - var asyncArrow = false; - switch (expr.type) { - case syntax_1.Syntax.Identifier: - break; - case ArrowParameterPlaceHolder: - params = expr.params; - asyncArrow = expr.async; - break; - default: - return null; - } - options = { - simple: true, - paramSet: {} - }; - for (var i = 0; i < params.length; ++i) { - var param = params[i]; - if (param.type === syntax_1.Syntax.AssignmentPattern) { - if (param.right.type === syntax_1.Syntax.YieldExpression) { - if (param.right.argument) { - this.throwUnexpectedToken(this.lookahead); - } - param.right.type = syntax_1.Syntax.Identifier; - param.right.name = 'yield'; - delete param.right.argument; - delete param.right.delegate; - } - } - else if (asyncArrow && param.type === syntax_1.Syntax.Identifier && param.name === 'await') { - this.throwUnexpectedToken(this.lookahead); - } - this.checkPatternParam(options, param); - params[i] = param; - } - if (this.context.strict || !this.context.allowYield) { - for (var i = 0; i < params.length; ++i) { - var param = params[i]; - if (param.type === syntax_1.Syntax.YieldExpression) { - this.throwUnexpectedToken(this.lookahead); - } - } - } - if (options.message === messages_1.Messages.StrictParamDupe) { - var token = this.context.strict ? options.stricted : options.firstRestricted; - this.throwUnexpectedToken(token, options.message); - } - return { - simple: options.simple, - params: params, - stricted: options.stricted, - firstRestricted: options.firstRestricted, - message: options.message - }; - }; - Parser.prototype.parseAssignmentExpression = function () { - var expr; - if (!this.context.allowYield && this.matchKeyword('yield')) { - expr = this.parseYieldExpression(); - } - else { - var startToken = this.lookahead; - var token = startToken; - expr = this.parseConditionalExpression(); - if (token.type === 3 /* Identifier */ && (token.lineNumber === this.lookahead.lineNumber) && token.value === 'async') { - if (this.lookahead.type === 3 /* Identifier */ || this.matchKeyword('yield')) { - var arg = this.parsePrimaryExpression(); - this.reinterpretExpressionAsPattern(arg); - expr = { - type: ArrowParameterPlaceHolder, - params: [arg], - async: true - }; - } - } - if (expr.type === ArrowParameterPlaceHolder || this.match('=>')) { - // https://tc39.github.io/ecma262/#sec-arrow-function-definitions - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - var isAsync = expr.async; - var list = this.reinterpretAsCoverFormalsList(expr); - if (list) { - if (this.hasLineTerminator) { - this.tolerateUnexpectedToken(this.lookahead); - } - this.context.firstCoverInitializedNameError = null; - var previousStrict = this.context.strict; - var previousAllowStrictDirective = this.context.allowStrictDirective; - this.context.allowStrictDirective = list.simple; - var previousAllowYield = this.context.allowYield; - var previousAwait = this.context.await; - this.context.allowYield = true; - this.context.await = isAsync; - var node = this.startNode(startToken); - this.expect('=>'); - var body = void 0; - if (this.match('{')) { - var previousAllowIn = this.context.allowIn; - this.context.allowIn = true; - body = this.parseFunctionSourceElements(); - this.context.allowIn = previousAllowIn; - } - else { - body = this.isolateCoverGrammar(this.parseAssignmentExpression); - } - var expression = body.type !== syntax_1.Syntax.BlockStatement; - if (this.context.strict && list.firstRestricted) { - this.throwUnexpectedToken(list.firstRestricted, list.message); - } - if (this.context.strict && list.stricted) { - this.tolerateUnexpectedToken(list.stricted, list.message); - } - expr = isAsync ? this.finalize(node, new Node.AsyncArrowFunctionExpression(list.params, body, expression)) : - this.finalize(node, new Node.ArrowFunctionExpression(list.params, body, expression)); - this.context.strict = previousStrict; - this.context.allowStrictDirective = previousAllowStrictDirective; - this.context.allowYield = previousAllowYield; - this.context.await = previousAwait; - } - } - else { - if (this.matchAssign()) { - if (!this.context.isAssignmentTarget) { - this.tolerateError(messages_1.Messages.InvalidLHSInAssignment); - } - if (this.context.strict && expr.type === syntax_1.Syntax.Identifier) { - var id = expr; - if (this.scanner.isRestrictedWord(id.name)) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictLHSAssignment); - } - if (this.scanner.isStrictModeReservedWord(id.name)) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); - } - } - if (!this.match('=')) { - this.context.isAssignmentTarget = false; - this.context.isBindingElement = false; - } - else { - this.reinterpretExpressionAsPattern(expr); - } - token = this.nextToken(); - var operator = token.value; - var right = this.isolateCoverGrammar(this.parseAssignmentExpression); - expr = this.finalize(this.startNode(startToken), new Node.AssignmentExpression(operator, expr, right)); - this.context.firstCoverInitializedNameError = null; - } - } - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-comma-operator - Parser.prototype.parseExpression = function () { - var startToken = this.lookahead; - var expr = this.isolateCoverGrammar(this.parseAssignmentExpression); - if (this.match(',')) { - var expressions = []; - expressions.push(expr); - while (this.lookahead.type !== 2 /* EOF */) { - if (!this.match(',')) { - break; - } - this.nextToken(); - expressions.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); - } - expr = this.finalize(this.startNode(startToken), new Node.SequenceExpression(expressions)); - } - return expr; - }; - // https://tc39.github.io/ecma262/#sec-block - Parser.prototype.parseStatementListItem = function () { - var statement; - this.context.isAssignmentTarget = true; - this.context.isBindingElement = true; - if (this.lookahead.type === 4 /* Keyword */) { - switch (this.lookahead.value) { - case 'export': - if (!this.context.isModule) { - this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalExportDeclaration); - } - statement = this.parseExportDeclaration(); - break; - case 'import': - if (!this.context.isModule) { - this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.IllegalImportDeclaration); - } - statement = this.parseImportDeclaration(); - break; - case 'const': - statement = this.parseLexicalDeclaration({ inFor: false }); - break; - case 'function': - // Apache CouchDB modification: add true to tolerate - // missing function identifiers. - statement = this.parseFunctionDeclaration(true); - break; - case 'class': - statement = this.parseClassDeclaration(); - break; - case 'let': - statement = this.isLexicalDeclaration() ? this.parseLexicalDeclaration({ inFor: false }) : this.parseStatement(); - break; - default: - statement = this.parseStatement(); - break; - } - } - else { - statement = this.parseStatement(); - } - return statement; - }; - Parser.prototype.parseBlock = function () { - var node = this.createNode(); - this.expect('{'); - var block = []; - while (true) { - if (this.match('}')) { - break; - } - block.push(this.parseStatementListItem()); - } - this.expect('}'); - return this.finalize(node, new Node.BlockStatement(block)); - }; - // https://tc39.github.io/ecma262/#sec-let-and-const-declarations - Parser.prototype.parseLexicalBinding = function (kind, options) { - var node = this.createNode(); - var params = []; - var id = this.parsePattern(params, kind); - if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { - if (this.scanner.isRestrictedWord(id.name)) { - this.tolerateError(messages_1.Messages.StrictVarName); - } - } - var init = null; - if (kind === 'const') { - if (!this.matchKeyword('in') && !this.matchContextualKeyword('of')) { - if (this.match('=')) { - this.nextToken(); - init = this.isolateCoverGrammar(this.parseAssignmentExpression); - } - else { - this.throwError(messages_1.Messages.DeclarationMissingInitializer, 'const'); - } - } - } - else if ((!options.inFor && id.type !== syntax_1.Syntax.Identifier) || this.match('=')) { - this.expect('='); - init = this.isolateCoverGrammar(this.parseAssignmentExpression); - } - return this.finalize(node, new Node.VariableDeclarator(id, init)); - }; - Parser.prototype.parseBindingList = function (kind, options) { - var list = [this.parseLexicalBinding(kind, options)]; - while (this.match(',')) { - this.nextToken(); - list.push(this.parseLexicalBinding(kind, options)); - } - return list; - }; - Parser.prototype.isLexicalDeclaration = function () { - var state = this.scanner.saveState(); - this.scanner.scanComments(); - var next = this.scanner.lex(); - this.scanner.restoreState(state); - return (next.type === 3 /* Identifier */) || - (next.type === 7 /* Punctuator */ && next.value === '[') || - (next.type === 7 /* Punctuator */ && next.value === '{') || - (next.type === 4 /* Keyword */ && next.value === 'let') || - (next.type === 4 /* Keyword */ && next.value === 'yield'); - }; - Parser.prototype.parseLexicalDeclaration = function (options) { - var node = this.createNode(); - var kind = this.nextToken().value; - assert_1.assert(kind === 'let' || kind === 'const', 'Lexical declaration must be either let or const'); - var declarations = this.parseBindingList(kind, options); - this.consumeSemicolon(); - return this.finalize(node, new Node.VariableDeclaration(declarations, kind)); - }; - // https://tc39.github.io/ecma262/#sec-destructuring-binding-patterns - Parser.prototype.parseBindingRestElement = function (params, kind) { - var node = this.createNode(); - this.expect('...'); - var arg = this.parsePattern(params, kind); - return this.finalize(node, new Node.RestElement(arg)); - }; - Parser.prototype.parseArrayPattern = function (params, kind) { - var node = this.createNode(); - this.expect('['); - var elements = []; - while (!this.match(']')) { - if (this.match(',')) { - this.nextToken(); - elements.push(null); - } - else { - if (this.match('...')) { - elements.push(this.parseBindingRestElement(params, kind)); - break; - } - else { - elements.push(this.parsePatternWithDefault(params, kind)); - } - if (!this.match(']')) { - this.expect(','); - } - } - } - this.expect(']'); - return this.finalize(node, new Node.ArrayPattern(elements)); - }; - Parser.prototype.parsePropertyPattern = function (params, kind) { - var node = this.createNode(); - var computed = false; - var shorthand = false; - var method = false; - var key; - var value; - if (this.lookahead.type === 3 /* Identifier */) { - var keyToken = this.lookahead; - key = this.parseVariableIdentifier(); - var init = this.finalize(node, new Node.Identifier(keyToken.value)); - if (this.match('=')) { - params.push(keyToken); - shorthand = true; - this.nextToken(); - var expr = this.parseAssignmentExpression(); - value = this.finalize(this.startNode(keyToken), new Node.AssignmentPattern(init, expr)); - } - else if (!this.match(':')) { - params.push(keyToken); - shorthand = true; - value = init; - } - else { - this.expect(':'); - value = this.parsePatternWithDefault(params, kind); - } - } - else { - computed = this.match('['); - key = this.parseObjectPropertyKey(); - this.expect(':'); - value = this.parsePatternWithDefault(params, kind); - } - return this.finalize(node, new Node.Property('init', key, computed, value, method, shorthand)); - }; - Parser.prototype.parseObjectPattern = function (params, kind) { - var node = this.createNode(); - var properties = []; - this.expect('{'); - while (!this.match('}')) { - properties.push(this.parsePropertyPattern(params, kind)); - if (!this.match('}')) { - this.expect(','); - } - } - this.expect('}'); - return this.finalize(node, new Node.ObjectPattern(properties)); - }; - Parser.prototype.parsePattern = function (params, kind) { - var pattern; - if (this.match('[')) { - pattern = this.parseArrayPattern(params, kind); - } - else if (this.match('{')) { - pattern = this.parseObjectPattern(params, kind); - } - else { - if (this.matchKeyword('let') && (kind === 'const' || kind === 'let')) { - this.tolerateUnexpectedToken(this.lookahead, messages_1.Messages.LetInLexicalBinding); - } - params.push(this.lookahead); - pattern = this.parseVariableIdentifier(kind); - } - return pattern; - }; - Parser.prototype.parsePatternWithDefault = function (params, kind) { - var startToken = this.lookahead; - var pattern = this.parsePattern(params, kind); - if (this.match('=')) { - this.nextToken(); - var previousAllowYield = this.context.allowYield; - this.context.allowYield = true; - var right = this.isolateCoverGrammar(this.parseAssignmentExpression); - this.context.allowYield = previousAllowYield; - pattern = this.finalize(this.startNode(startToken), new Node.AssignmentPattern(pattern, right)); - } - return pattern; - }; - // https://tc39.github.io/ecma262/#sec-variable-statement - Parser.prototype.parseVariableIdentifier = function (kind) { - var node = this.createNode(); - var token = this.nextToken(); - if (token.type === 4 /* Keyword */ && token.value === 'yield') { - if (this.context.strict) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); - } - else if (!this.context.allowYield) { - this.throwUnexpectedToken(token); - } - } - else if (token.type !== 3 /* Identifier */) { - if (this.context.strict && token.type === 4 /* Keyword */ && this.scanner.isStrictModeReservedWord(token.value)) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictReservedWord); - } - else { - if (this.context.strict || token.value !== 'let' || kind !== 'var') { - this.throwUnexpectedToken(token); - } - } - } - else if ((this.context.isModule || this.context.await) && token.type === 3 /* Identifier */ && token.value === 'await') { - this.tolerateUnexpectedToken(token); - } - return this.finalize(node, new Node.Identifier(token.value)); - }; - Parser.prototype.parseVariableDeclaration = function (options) { - var node = this.createNode(); - var params = []; - var id = this.parsePattern(params, 'var'); - if (this.context.strict && id.type === syntax_1.Syntax.Identifier) { - if (this.scanner.isRestrictedWord(id.name)) { - this.tolerateError(messages_1.Messages.StrictVarName); - } - } - var init = null; - if (this.match('=')) { - this.nextToken(); - init = this.isolateCoverGrammar(this.parseAssignmentExpression); - } - else if (id.type !== syntax_1.Syntax.Identifier && !options.inFor) { - this.expect('='); - } - return this.finalize(node, new Node.VariableDeclarator(id, init)); - }; - Parser.prototype.parseVariableDeclarationList = function (options) { - var opt = { inFor: options.inFor }; - var list = []; - list.push(this.parseVariableDeclaration(opt)); - while (this.match(',')) { - this.nextToken(); - list.push(this.parseVariableDeclaration(opt)); - } - return list; - }; - Parser.prototype.parseVariableStatement = function () { - var node = this.createNode(); - this.expectKeyword('var'); - var declarations = this.parseVariableDeclarationList({ inFor: false }); - this.consumeSemicolon(); - return this.finalize(node, new Node.VariableDeclaration(declarations, 'var')); - }; - // https://tc39.github.io/ecma262/#sec-empty-statement - Parser.prototype.parseEmptyStatement = function () { - var node = this.createNode(); - this.expect(';'); - return this.finalize(node, new Node.EmptyStatement()); - }; - // https://tc39.github.io/ecma262/#sec-expression-statement - Parser.prototype.parseExpressionStatement = function () { - var node = this.createNode(); - var expr = this.parseExpression(); - this.consumeSemicolon(); - return this.finalize(node, new Node.ExpressionStatement(expr)); - }; - // https://tc39.github.io/ecma262/#sec-if-statement - Parser.prototype.parseIfClause = function () { - if (this.context.strict && this.matchKeyword('function')) { - this.tolerateError(messages_1.Messages.StrictFunction); - } - return this.parseStatement(); - }; - Parser.prototype.parseIfStatement = function () { - var node = this.createNode(); - var consequent; - var alternate = null; - this.expectKeyword('if'); - this.expect('('); - var test = this.parseExpression(); - if (!this.match(')') && this.config.tolerant) { - this.tolerateUnexpectedToken(this.nextToken()); - consequent = this.finalize(this.createNode(), new Node.EmptyStatement()); - } - else { - this.expect(')'); - consequent = this.parseIfClause(); - if (this.matchKeyword('else')) { - this.nextToken(); - alternate = this.parseIfClause(); - } - } - return this.finalize(node, new Node.IfStatement(test, consequent, alternate)); - }; - // https://tc39.github.io/ecma262/#sec-do-while-statement - Parser.prototype.parseDoWhileStatement = function () { - var node = this.createNode(); - this.expectKeyword('do'); - var previousInIteration = this.context.inIteration; - this.context.inIteration = true; - var body = this.parseStatement(); - this.context.inIteration = previousInIteration; - this.expectKeyword('while'); - this.expect('('); - var test = this.parseExpression(); - if (!this.match(')') && this.config.tolerant) { - this.tolerateUnexpectedToken(this.nextToken()); - } - else { - this.expect(')'); - if (this.match(';')) { - this.nextToken(); - } - } - return this.finalize(node, new Node.DoWhileStatement(body, test)); - }; - // https://tc39.github.io/ecma262/#sec-while-statement - Parser.prototype.parseWhileStatement = function () { - var node = this.createNode(); - var body; - this.expectKeyword('while'); - this.expect('('); - var test = this.parseExpression(); - if (!this.match(')') && this.config.tolerant) { - this.tolerateUnexpectedToken(this.nextToken()); - body = this.finalize(this.createNode(), new Node.EmptyStatement()); - } - else { - this.expect(')'); - var previousInIteration = this.context.inIteration; - this.context.inIteration = true; - body = this.parseStatement(); - this.context.inIteration = previousInIteration; - } - return this.finalize(node, new Node.WhileStatement(test, body)); - }; - // https://tc39.github.io/ecma262/#sec-for-statement - // https://tc39.github.io/ecma262/#sec-for-in-and-for-of-statements - Parser.prototype.parseForStatement = function () { - var init = null; - var test = null; - var update = null; - var forIn = true; - var left, right; - var node = this.createNode(); - this.expectKeyword('for'); - this.expect('('); - if (this.match(';')) { - this.nextToken(); - } - else { - if (this.matchKeyword('var')) { - init = this.createNode(); - this.nextToken(); - var previousAllowIn = this.context.allowIn; - this.context.allowIn = false; - var declarations = this.parseVariableDeclarationList({ inFor: true }); - this.context.allowIn = previousAllowIn; - if (declarations.length === 1 && this.matchKeyword('in')) { - var decl = declarations[0]; - if (decl.init && (decl.id.type === syntax_1.Syntax.ArrayPattern || decl.id.type === syntax_1.Syntax.ObjectPattern || this.context.strict)) { - this.tolerateError(messages_1.Messages.ForInOfLoopInitializer, 'for-in'); - } - init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); - this.nextToken(); - left = init; - right = this.parseExpression(); - init = null; - } - else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { - init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); - this.nextToken(); - left = init; - right = this.parseAssignmentExpression(); - init = null; - forIn = false; - } - else { - init = this.finalize(init, new Node.VariableDeclaration(declarations, 'var')); - this.expect(';'); - } - } - else if (this.matchKeyword('const') || this.matchKeyword('let')) { - init = this.createNode(); - var kind = this.nextToken().value; - if (!this.context.strict && this.lookahead.value === 'in') { - init = this.finalize(init, new Node.Identifier(kind)); - this.nextToken(); - left = init; - right = this.parseExpression(); - init = null; - } - else { - var previousAllowIn = this.context.allowIn; - this.context.allowIn = false; - var declarations = this.parseBindingList(kind, { inFor: true }); - this.context.allowIn = previousAllowIn; - if (declarations.length === 1 && declarations[0].init === null && this.matchKeyword('in')) { - init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); - this.nextToken(); - left = init; - right = this.parseExpression(); - init = null; - } - else if (declarations.length === 1 && declarations[0].init === null && this.matchContextualKeyword('of')) { - init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); - this.nextToken(); - left = init; - right = this.parseAssignmentExpression(); - init = null; - forIn = false; - } - else { - this.consumeSemicolon(); - init = this.finalize(init, new Node.VariableDeclaration(declarations, kind)); - } - } - } - else { - var initStartToken = this.lookahead; - var previousAllowIn = this.context.allowIn; - this.context.allowIn = false; - init = this.inheritCoverGrammar(this.parseAssignmentExpression); - this.context.allowIn = previousAllowIn; - if (this.matchKeyword('in')) { - if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { - this.tolerateError(messages_1.Messages.InvalidLHSInForIn); - } - this.nextToken(); - this.reinterpretExpressionAsPattern(init); - left = init; - right = this.parseExpression(); - init = null; - } - else if (this.matchContextualKeyword('of')) { - if (!this.context.isAssignmentTarget || init.type === syntax_1.Syntax.AssignmentExpression) { - this.tolerateError(messages_1.Messages.InvalidLHSInForLoop); - } - this.nextToken(); - this.reinterpretExpressionAsPattern(init); - left = init; - right = this.parseAssignmentExpression(); - init = null; - forIn = false; - } - else { - if (this.match(',')) { - var initSeq = [init]; - while (this.match(',')) { - this.nextToken(); - initSeq.push(this.isolateCoverGrammar(this.parseAssignmentExpression)); - } - init = this.finalize(this.startNode(initStartToken), new Node.SequenceExpression(initSeq)); - } - this.expect(';'); - } - } - } - if (typeof left === 'undefined') { - if (!this.match(';')) { - test = this.parseExpression(); - } - this.expect(';'); - if (!this.match(')')) { - update = this.parseExpression(); - } - } - var body; - if (!this.match(')') && this.config.tolerant) { - this.tolerateUnexpectedToken(this.nextToken()); - body = this.finalize(this.createNode(), new Node.EmptyStatement()); - } - else { - this.expect(')'); - var previousInIteration = this.context.inIteration; - this.context.inIteration = true; - body = this.isolateCoverGrammar(this.parseStatement); - this.context.inIteration = previousInIteration; - } - return (typeof left === 'undefined') ? - this.finalize(node, new Node.ForStatement(init, test, update, body)) : - forIn ? this.finalize(node, new Node.ForInStatement(left, right, body)) : - this.finalize(node, new Node.ForOfStatement(left, right, body)); - }; - // https://tc39.github.io/ecma262/#sec-continue-statement - Parser.prototype.parseContinueStatement = function () { - var node = this.createNode(); - this.expectKeyword('continue'); - var label = null; - if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { - var id = this.parseVariableIdentifier(); - label = id; - var key = '$' + id.name; - if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { - this.throwError(messages_1.Messages.UnknownLabel, id.name); - } - } - this.consumeSemicolon(); - if (label === null && !this.context.inIteration) { - this.throwError(messages_1.Messages.IllegalContinue); - } - return this.finalize(node, new Node.ContinueStatement(label)); - }; - // https://tc39.github.io/ecma262/#sec-break-statement - Parser.prototype.parseBreakStatement = function () { - var node = this.createNode(); - this.expectKeyword('break'); - var label = null; - if (this.lookahead.type === 3 /* Identifier */ && !this.hasLineTerminator) { - var id = this.parseVariableIdentifier(); - var key = '$' + id.name; - if (!Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { - this.throwError(messages_1.Messages.UnknownLabel, id.name); - } - label = id; - } - this.consumeSemicolon(); - if (label === null && !this.context.inIteration && !this.context.inSwitch) { - this.throwError(messages_1.Messages.IllegalBreak); - } - return this.finalize(node, new Node.BreakStatement(label)); - }; - // https://tc39.github.io/ecma262/#sec-return-statement - Parser.prototype.parseReturnStatement = function () { - if (!this.context.inFunctionBody) { - this.tolerateError(messages_1.Messages.IllegalReturn); - } - var node = this.createNode(); - this.expectKeyword('return'); - var hasArgument = (!this.match(';') && !this.match('}') && - !this.hasLineTerminator && this.lookahead.type !== 2 /* EOF */) || - this.lookahead.type === 8 /* StringLiteral */ || - this.lookahead.type === 10 /* Template */; - var argument = hasArgument ? this.parseExpression() : null; - this.consumeSemicolon(); - return this.finalize(node, new Node.ReturnStatement(argument)); - }; - // https://tc39.github.io/ecma262/#sec-with-statement - Parser.prototype.parseWithStatement = function () { - if (this.context.strict) { - this.tolerateError(messages_1.Messages.StrictModeWith); - } - var node = this.createNode(); - var body; - this.expectKeyword('with'); - this.expect('('); - var object = this.parseExpression(); - if (!this.match(')') && this.config.tolerant) { - this.tolerateUnexpectedToken(this.nextToken()); - body = this.finalize(this.createNode(), new Node.EmptyStatement()); - } - else { - this.expect(')'); - body = this.parseStatement(); - } - return this.finalize(node, new Node.WithStatement(object, body)); - }; - // https://tc39.github.io/ecma262/#sec-switch-statement - Parser.prototype.parseSwitchCase = function () { - var node = this.createNode(); - var test; - if (this.matchKeyword('default')) { - this.nextToken(); - test = null; - } - else { - this.expectKeyword('case'); - test = this.parseExpression(); - } - this.expect(':'); - var consequent = []; - while (true) { - if (this.match('}') || this.matchKeyword('default') || this.matchKeyword('case')) { - break; - } - consequent.push(this.parseStatementListItem()); - } - return this.finalize(node, new Node.SwitchCase(test, consequent)); - }; - Parser.prototype.parseSwitchStatement = function () { - var node = this.createNode(); - this.expectKeyword('switch'); - this.expect('('); - var discriminant = this.parseExpression(); - this.expect(')'); - var previousInSwitch = this.context.inSwitch; - this.context.inSwitch = true; - var cases = []; - var defaultFound = false; - this.expect('{'); - while (true) { - if (this.match('}')) { - break; - } - var clause = this.parseSwitchCase(); - if (clause.test === null) { - if (defaultFound) { - this.throwError(messages_1.Messages.MultipleDefaultsInSwitch); - } - defaultFound = true; - } - cases.push(clause); - } - this.expect('}'); - this.context.inSwitch = previousInSwitch; - return this.finalize(node, new Node.SwitchStatement(discriminant, cases)); - }; - // https://tc39.github.io/ecma262/#sec-labelled-statements - Parser.prototype.parseLabelledStatement = function () { - var node = this.createNode(); - var expr = this.parseExpression(); - var statement; - if ((expr.type === syntax_1.Syntax.Identifier) && this.match(':')) { - this.nextToken(); - var id = expr; - var key = '$' + id.name; - if (Object.prototype.hasOwnProperty.call(this.context.labelSet, key)) { - this.throwError(messages_1.Messages.Redeclaration, 'Label', id.name); - } - this.context.labelSet[key] = true; - var body = void 0; - if (this.matchKeyword('class')) { - this.tolerateUnexpectedToken(this.lookahead); - body = this.parseClassDeclaration(); - } - else if (this.matchKeyword('function')) { - var token = this.lookahead; - var declaration = this.parseFunctionDeclaration(); - if (this.context.strict) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunction); - } - else if (declaration.generator) { - this.tolerateUnexpectedToken(token, messages_1.Messages.GeneratorInLegacyContext); - } - body = declaration; - } - else { - body = this.parseStatement(); - } - delete this.context.labelSet[key]; - statement = new Node.LabeledStatement(id, body); - } - else { - this.consumeSemicolon(); - statement = new Node.ExpressionStatement(expr); - } - return this.finalize(node, statement); - }; - // https://tc39.github.io/ecma262/#sec-throw-statement - Parser.prototype.parseThrowStatement = function () { - var node = this.createNode(); - this.expectKeyword('throw'); - if (this.hasLineTerminator) { - this.throwError(messages_1.Messages.NewlineAfterThrow); - } - var argument = this.parseExpression(); - this.consumeSemicolon(); - return this.finalize(node, new Node.ThrowStatement(argument)); - }; - // https://tc39.github.io/ecma262/#sec-try-statement - Parser.prototype.parseCatchClause = function () { - var node = this.createNode(); - this.expectKeyword('catch'); - this.expect('('); - if (this.match(')')) { - this.throwUnexpectedToken(this.lookahead); - } - var params = []; - var param = this.parsePattern(params); - var paramMap = {}; - for (var i = 0; i < params.length; i++) { - var key = '$' + params[i].value; - if (Object.prototype.hasOwnProperty.call(paramMap, key)) { - this.tolerateError(messages_1.Messages.DuplicateBinding, params[i].value); - } - paramMap[key] = true; - } - if (this.context.strict && param.type === syntax_1.Syntax.Identifier) { - if (this.scanner.isRestrictedWord(param.name)) { - this.tolerateError(messages_1.Messages.StrictCatchVariable); - } - } - this.expect(')'); - var body = this.parseBlock(); - return this.finalize(node, new Node.CatchClause(param, body)); - }; - Parser.prototype.parseFinallyClause = function () { - this.expectKeyword('finally'); - return this.parseBlock(); - }; - Parser.prototype.parseTryStatement = function () { - var node = this.createNode(); - this.expectKeyword('try'); - var block = this.parseBlock(); - var handler = this.matchKeyword('catch') ? this.parseCatchClause() : null; - var finalizer = this.matchKeyword('finally') ? this.parseFinallyClause() : null; - if (!handler && !finalizer) { - this.throwError(messages_1.Messages.NoCatchOrFinally); - } - return this.finalize(node, new Node.TryStatement(block, handler, finalizer)); - }; - // https://tc39.github.io/ecma262/#sec-debugger-statement - Parser.prototype.parseDebuggerStatement = function () { - var node = this.createNode(); - this.expectKeyword('debugger'); - this.consumeSemicolon(); - return this.finalize(node, new Node.DebuggerStatement()); - }; - // https://tc39.github.io/ecma262/#sec-ecmascript-language-statements-and-declarations - Parser.prototype.parseStatement = function () { - var statement; - switch (this.lookahead.type) { - case 1 /* BooleanLiteral */: - case 5 /* NullLiteral */: - case 6 /* NumericLiteral */: - case 8 /* StringLiteral */: - case 10 /* Template */: - case 9 /* RegularExpression */: - statement = this.parseExpressionStatement(); - break; - case 7 /* Punctuator */: - var value = this.lookahead.value; - if (value === '{') { - statement = this.parseBlock(); - } - else if (value === '(') { - statement = this.parseExpressionStatement(); - } - else if (value === ';') { - statement = this.parseEmptyStatement(); - } - else { - statement = this.parseExpressionStatement(); - } - break; - case 3 /* Identifier */: - statement = this.matchAsyncFunction() ? this.parseFunctionDeclaration() : this.parseLabelledStatement(); - break; - case 4 /* Keyword */: - switch (this.lookahead.value) { - case 'break': - statement = this.parseBreakStatement(); - break; - case 'continue': - statement = this.parseContinueStatement(); - break; - case 'debugger': - statement = this.parseDebuggerStatement(); - break; - case 'do': - statement = this.parseDoWhileStatement(); - break; - case 'for': - statement = this.parseForStatement(); - break; - case 'function': - statement = this.parseFunctionDeclaration(); - break; - case 'if': - statement = this.parseIfStatement(); - break; - case 'return': - statement = this.parseReturnStatement(); - break; - case 'switch': - statement = this.parseSwitchStatement(); - break; - case 'throw': - statement = this.parseThrowStatement(); - break; - case 'try': - statement = this.parseTryStatement(); - break; - case 'var': - statement = this.parseVariableStatement(); - break; - case 'while': - statement = this.parseWhileStatement(); - break; - case 'with': - statement = this.parseWithStatement(); - break; - default: - statement = this.parseExpressionStatement(); - break; - } - break; - default: - statement = this.throwUnexpectedToken(this.lookahead); - } - return statement; - }; - // https://tc39.github.io/ecma262/#sec-function-definitions - Parser.prototype.parseFunctionSourceElements = function () { - var node = this.createNode(); - this.expect('{'); - var body = this.parseDirectivePrologues(); - var previousLabelSet = this.context.labelSet; - var previousInIteration = this.context.inIteration; - var previousInSwitch = this.context.inSwitch; - var previousInFunctionBody = this.context.inFunctionBody; - this.context.labelSet = {}; - this.context.inIteration = false; - this.context.inSwitch = false; - this.context.inFunctionBody = true; - while (this.lookahead.type !== 2 /* EOF */) { - if (this.match('}')) { - break; - } - body.push(this.parseStatementListItem()); - } - this.expect('}'); - this.context.labelSet = previousLabelSet; - this.context.inIteration = previousInIteration; - this.context.inSwitch = previousInSwitch; - this.context.inFunctionBody = previousInFunctionBody; - return this.finalize(node, new Node.BlockStatement(body)); - }; - Parser.prototype.validateParam = function (options, param, name) { - var key = '$' + name; - if (this.context.strict) { - if (this.scanner.isRestrictedWord(name)) { - options.stricted = param; - options.message = messages_1.Messages.StrictParamName; - } - if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { - options.stricted = param; - options.message = messages_1.Messages.StrictParamDupe; - } - } - else if (!options.firstRestricted) { - if (this.scanner.isRestrictedWord(name)) { - options.firstRestricted = param; - options.message = messages_1.Messages.StrictParamName; - } - else if (this.scanner.isStrictModeReservedWord(name)) { - options.firstRestricted = param; - options.message = messages_1.Messages.StrictReservedWord; - } - else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { - options.stricted = param; - options.message = messages_1.Messages.StrictParamDupe; - } - } - /* istanbul ignore next */ - if (typeof Object.defineProperty === 'function') { - Object.defineProperty(options.paramSet, key, { value: true, enumerable: true, writable: true, configurable: true }); - } - else { - options.paramSet[key] = true; - } - }; - Parser.prototype.parseRestElement = function (params) { - var node = this.createNode(); - this.expect('...'); - var arg = this.parsePattern(params); - if (this.match('=')) { - this.throwError(messages_1.Messages.DefaultRestParameter); - } - if (!this.match(')')) { - this.throwError(messages_1.Messages.ParameterAfterRestParameter); - } - return this.finalize(node, new Node.RestElement(arg)); - }; - Parser.prototype.parseFormalParameter = function (options) { - var params = []; - var param = this.match('...') ? this.parseRestElement(params) : this.parsePatternWithDefault(params); - for (var i = 0; i < params.length; i++) { - this.validateParam(options, params[i], params[i].value); - } - options.simple = options.simple && (param instanceof Node.Identifier); - options.params.push(param); - }; - Parser.prototype.parseFormalParameters = function (firstRestricted) { - var options; - options = { - simple: true, - params: [], - firstRestricted: firstRestricted - }; - this.expect('('); - if (!this.match(')')) { - options.paramSet = {}; - while (this.lookahead.type !== 2 /* EOF */) { - this.parseFormalParameter(options); - if (this.match(')')) { - break; - } - this.expect(','); - if (this.match(')')) { - break; - } - } - } - this.expect(')'); - return { - simple: options.simple, - params: options.params, - stricted: options.stricted, - firstRestricted: options.firstRestricted, - message: options.message - }; - }; - Parser.prototype.matchAsyncFunction = function () { - var match = this.matchContextualKeyword('async'); - if (match) { - var state = this.scanner.saveState(); - this.scanner.scanComments(); - var next = this.scanner.lex(); - this.scanner.restoreState(state); - match = (state.lineNumber === next.lineNumber) && (next.type === 4 /* Keyword */) && (next.value === 'function'); - } - return match; - }; - Parser.prototype.parseFunctionDeclaration = function (identifierIsOptional) { - var node = this.createNode(); - var isAsync = this.matchContextualKeyword('async'); - if (isAsync) { - this.nextToken(); - } - this.expectKeyword('function'); - var isGenerator = isAsync ? false : this.match('*'); - if (isGenerator) { - this.nextToken(); - } - var message; - var id = null; - var firstRestricted = null; - if (!identifierIsOptional || !this.match('(')) { - var token = this.lookahead; - id = this.parseVariableIdentifier(); - if (this.context.strict) { - if (this.scanner.isRestrictedWord(token.value)) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); - } - } - else { - if (this.scanner.isRestrictedWord(token.value)) { - firstRestricted = token; - message = messages_1.Messages.StrictFunctionName; - } - else if (this.scanner.isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = messages_1.Messages.StrictReservedWord; - } - } - } - var previousAllowAwait = this.context.await; - var previousAllowYield = this.context.allowYield; - this.context.await = isAsync; - this.context.allowYield = !isGenerator; - var formalParameters = this.parseFormalParameters(firstRestricted); - var params = formalParameters.params; - var stricted = formalParameters.stricted; - firstRestricted = formalParameters.firstRestricted; - if (formalParameters.message) { - message = formalParameters.message; - } - var previousStrict = this.context.strict; - var previousAllowStrictDirective = this.context.allowStrictDirective; - this.context.allowStrictDirective = formalParameters.simple; - var body = this.parseFunctionSourceElements(); - if (this.context.strict && firstRestricted) { - this.throwUnexpectedToken(firstRestricted, message); - } - if (this.context.strict && stricted) { - this.tolerateUnexpectedToken(stricted, message); - } - this.context.strict = previousStrict; - this.context.allowStrictDirective = previousAllowStrictDirective; - this.context.await = previousAllowAwait; - this.context.allowYield = previousAllowYield; - return isAsync ? this.finalize(node, new Node.AsyncFunctionDeclaration(id, params, body)) : - this.finalize(node, new Node.FunctionDeclaration(id, params, body, isGenerator)); - }; - Parser.prototype.parseFunctionExpression = function () { - var node = this.createNode(); - var isAsync = this.matchContextualKeyword('async'); - if (isAsync) { - this.nextToken(); - } - this.expectKeyword('function'); - var isGenerator = isAsync ? false : this.match('*'); - if (isGenerator) { - this.nextToken(); - } - var message; - var id = null; - var firstRestricted; - var previousAllowAwait = this.context.await; - var previousAllowYield = this.context.allowYield; - this.context.await = isAsync; - this.context.allowYield = !isGenerator; - if (!this.match('(')) { - var token = this.lookahead; - id = (!this.context.strict && !isGenerator && this.matchKeyword('yield')) ? this.parseIdentifierName() : this.parseVariableIdentifier(); - if (this.context.strict) { - if (this.scanner.isRestrictedWord(token.value)) { - this.tolerateUnexpectedToken(token, messages_1.Messages.StrictFunctionName); - } - } - else { - if (this.scanner.isRestrictedWord(token.value)) { - firstRestricted = token; - message = messages_1.Messages.StrictFunctionName; - } - else if (this.scanner.isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = messages_1.Messages.StrictReservedWord; - } - } - } - var formalParameters = this.parseFormalParameters(firstRestricted); - var params = formalParameters.params; - var stricted = formalParameters.stricted; - firstRestricted = formalParameters.firstRestricted; - if (formalParameters.message) { - message = formalParameters.message; - } - var previousStrict = this.context.strict; - var previousAllowStrictDirective = this.context.allowStrictDirective; - this.context.allowStrictDirective = formalParameters.simple; - var body = this.parseFunctionSourceElements(); - if (this.context.strict && firstRestricted) { - this.throwUnexpectedToken(firstRestricted, message); - } - if (this.context.strict && stricted) { - this.tolerateUnexpectedToken(stricted, message); - } - this.context.strict = previousStrict; - this.context.allowStrictDirective = previousAllowStrictDirective; - this.context.await = previousAllowAwait; - this.context.allowYield = previousAllowYield; - return isAsync ? this.finalize(node, new Node.AsyncFunctionExpression(id, params, body)) : - this.finalize(node, new Node.FunctionExpression(id, params, body, isGenerator)); - }; - // https://tc39.github.io/ecma262/#sec-directive-prologues-and-the-use-strict-directive - Parser.prototype.parseDirective = function () { - var token = this.lookahead; - var node = this.createNode(); - var expr = this.parseExpression(); - var directive = (expr.type === syntax_1.Syntax.Literal) ? this.getTokenRaw(token).slice(1, -1) : null; - this.consumeSemicolon(); - return this.finalize(node, directive ? new Node.Directive(expr, directive) : new Node.ExpressionStatement(expr)); - }; - Parser.prototype.parseDirectivePrologues = function () { - var firstRestricted = null; - var body = []; - while (true) { - var token = this.lookahead; - if (token.type !== 8 /* StringLiteral */) { - break; - } - var statement = this.parseDirective(); - body.push(statement); - var directive = statement.directive; - if (typeof directive !== 'string') { - break; - } - if (directive === 'use strict') { - this.context.strict = true; - if (firstRestricted) { - this.tolerateUnexpectedToken(firstRestricted, messages_1.Messages.StrictOctalLiteral); - } - if (!this.context.allowStrictDirective) { - this.tolerateUnexpectedToken(token, messages_1.Messages.IllegalLanguageModeDirective); - } - } - else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - return body; - }; - // https://tc39.github.io/ecma262/#sec-method-definitions - Parser.prototype.qualifiedPropertyName = function (token) { - switch (token.type) { - case 3 /* Identifier */: - case 8 /* StringLiteral */: - case 1 /* BooleanLiteral */: - case 5 /* NullLiteral */: - case 6 /* NumericLiteral */: - case 4 /* Keyword */: - return true; - case 7 /* Punctuator */: - return token.value === '['; - default: - break; - } - return false; - }; - Parser.prototype.parseGetterMethod = function () { - var node = this.createNode(); - var isGenerator = false; - var previousAllowYield = this.context.allowYield; - this.context.allowYield = !isGenerator; - var formalParameters = this.parseFormalParameters(); - if (formalParameters.params.length > 0) { - this.tolerateError(messages_1.Messages.BadGetterArity); - } - var method = this.parsePropertyMethod(formalParameters); - this.context.allowYield = previousAllowYield; - return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); - }; - Parser.prototype.parseSetterMethod = function () { - var node = this.createNode(); - var isGenerator = false; - var previousAllowYield = this.context.allowYield; - this.context.allowYield = !isGenerator; - var formalParameters = this.parseFormalParameters(); - if (formalParameters.params.length !== 1) { - this.tolerateError(messages_1.Messages.BadSetterArity); - } - else if (formalParameters.params[0] instanceof Node.RestElement) { - this.tolerateError(messages_1.Messages.BadSetterRestParameter); - } - var method = this.parsePropertyMethod(formalParameters); - this.context.allowYield = previousAllowYield; - return this.finalize(node, new Node.FunctionExpression(null, formalParameters.params, method, isGenerator)); - }; - Parser.prototype.parseGeneratorMethod = function () { - var node = this.createNode(); - var isGenerator = true; - var previousAllowYield = this.context.allowYield; - this.context.allowYield = true; - var params = this.parseFormalParameters(); - this.context.allowYield = false; - var method = this.parsePropertyMethod(params); - this.context.allowYield = previousAllowYield; - return this.finalize(node, new Node.FunctionExpression(null, params.params, method, isGenerator)); - }; - // https://tc39.github.io/ecma262/#sec-generator-function-definitions - Parser.prototype.isStartOfExpression = function () { - var start = true; - var value = this.lookahead.value; - switch (this.lookahead.type) { - case 7 /* Punctuator */: - start = (value === '[') || (value === '(') || (value === '{') || - (value === '+') || (value === '-') || - (value === '!') || (value === '~') || - (value === '++') || (value === '--') || - (value === '/') || (value === '/='); // regular expression literal - break; - case 4 /* Keyword */: - start = (value === 'class') || (value === 'delete') || - (value === 'function') || (value === 'let') || (value === 'new') || - (value === 'super') || (value === 'this') || (value === 'typeof') || - (value === 'void') || (value === 'yield'); - break; - default: - break; - } - return start; - }; - Parser.prototype.parseYieldExpression = function () { - var node = this.createNode(); - this.expectKeyword('yield'); - var argument = null; - var delegate = false; - if (!this.hasLineTerminator) { - var previousAllowYield = this.context.allowYield; - this.context.allowYield = false; - delegate = this.match('*'); - if (delegate) { - this.nextToken(); - argument = this.parseAssignmentExpression(); - } - else if (this.isStartOfExpression()) { - argument = this.parseAssignmentExpression(); - } - this.context.allowYield = previousAllowYield; - } - return this.finalize(node, new Node.YieldExpression(argument, delegate)); - }; - // https://tc39.github.io/ecma262/#sec-class-definitions - Parser.prototype.parseClassElement = function (hasConstructor) { - var token = this.lookahead; - var node = this.createNode(); - var kind = ''; - var key = null; - var value = null; - var computed = false; - var method = false; - var isStatic = false; - var isAsync = false; - if (this.match('*')) { - this.nextToken(); - } - else { - computed = this.match('['); - key = this.parseObjectPropertyKey(); - var id = key; - if (id.name === 'static' && (this.qualifiedPropertyName(this.lookahead) || this.match('*'))) { - token = this.lookahead; - isStatic = true; - computed = this.match('['); - if (this.match('*')) { - this.nextToken(); - } - else { - key = this.parseObjectPropertyKey(); - } - } - if ((token.type === 3 /* Identifier */) && !this.hasLineTerminator && (token.value === 'async')) { - var punctuator = this.lookahead.value; - if (punctuator !== ':' && punctuator !== '(' && punctuator !== '*') { - isAsync = true; - token = this.lookahead; - key = this.parseObjectPropertyKey(); - if (token.type === 3 /* Identifier */ && token.value === 'constructor') { - this.tolerateUnexpectedToken(token, messages_1.Messages.ConstructorIsAsync); - } - } - } - } - var lookaheadPropertyKey = this.qualifiedPropertyName(this.lookahead); - if (token.type === 3 /* Identifier */) { - if (token.value === 'get' && lookaheadPropertyKey) { - kind = 'get'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - this.context.allowYield = false; - value = this.parseGetterMethod(); - } - else if (token.value === 'set' && lookaheadPropertyKey) { - kind = 'set'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - value = this.parseSetterMethod(); - } - } - else if (token.type === 7 /* Punctuator */ && token.value === '*' && lookaheadPropertyKey) { - kind = 'init'; - computed = this.match('['); - key = this.parseObjectPropertyKey(); - value = this.parseGeneratorMethod(); - method = true; - } - if (!kind && key && this.match('(')) { - kind = 'init'; - value = isAsync ? this.parsePropertyMethodAsyncFunction() : this.parsePropertyMethodFunction(); - method = true; - } - if (!kind) { - this.throwUnexpectedToken(this.lookahead); - } - if (kind === 'init') { - kind = 'method'; - } - if (!computed) { - if (isStatic && this.isPropertyKey(key, 'prototype')) { - this.throwUnexpectedToken(token, messages_1.Messages.StaticPrototype); - } - if (!isStatic && this.isPropertyKey(key, 'constructor')) { - if (kind !== 'method' || !method || (value && value.generator)) { - this.throwUnexpectedToken(token, messages_1.Messages.ConstructorSpecialMethod); - } - if (hasConstructor.value) { - this.throwUnexpectedToken(token, messages_1.Messages.DuplicateConstructor); - } - else { - hasConstructor.value = true; - } - kind = 'constructor'; - } - } - return this.finalize(node, new Node.MethodDefinition(key, computed, value, kind, isStatic)); - }; - Parser.prototype.parseClassElementList = function () { - var body = []; - var hasConstructor = { value: false }; - this.expect('{'); - while (!this.match('}')) { - if (this.match(';')) { - this.nextToken(); - } - else { - body.push(this.parseClassElement(hasConstructor)); - } - } - this.expect('}'); - return body; - }; - Parser.prototype.parseClassBody = function () { - var node = this.createNode(); - var elementList = this.parseClassElementList(); - return this.finalize(node, new Node.ClassBody(elementList)); - }; - Parser.prototype.parseClassDeclaration = function (identifierIsOptional) { - var node = this.createNode(); - var previousStrict = this.context.strict; - this.context.strict = true; - this.expectKeyword('class'); - var id = (identifierIsOptional && (this.lookahead.type !== 3 /* Identifier */)) ? null : this.parseVariableIdentifier(); - var superClass = null; - if (this.matchKeyword('extends')) { - this.nextToken(); - superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); - } - var classBody = this.parseClassBody(); - this.context.strict = previousStrict; - return this.finalize(node, new Node.ClassDeclaration(id, superClass, classBody)); - }; - Parser.prototype.parseClassExpression = function () { - var node = this.createNode(); - var previousStrict = this.context.strict; - this.context.strict = true; - this.expectKeyword('class'); - var id = (this.lookahead.type === 3 /* Identifier */) ? this.parseVariableIdentifier() : null; - var superClass = null; - if (this.matchKeyword('extends')) { - this.nextToken(); - superClass = this.isolateCoverGrammar(this.parseLeftHandSideExpressionAllowCall); - } - var classBody = this.parseClassBody(); - this.context.strict = previousStrict; - return this.finalize(node, new Node.ClassExpression(id, superClass, classBody)); - }; - // https://tc39.github.io/ecma262/#sec-scripts - // https://tc39.github.io/ecma262/#sec-modules - Parser.prototype.parseModule = function () { - this.context.strict = true; - this.context.isModule = true; - this.scanner.isModule = true; - var node = this.createNode(); - var body = this.parseDirectivePrologues(); - while (this.lookahead.type !== 2 /* EOF */) { - body.push(this.parseStatementListItem()); - } - return this.finalize(node, new Node.Module(body)); - }; - Parser.prototype.parseScript = function () { - var node = this.createNode(); - var body = this.parseDirectivePrologues(); - while (this.lookahead.type !== 2 /* EOF */) { - body.push(this.parseStatementListItem()); - } - return this.finalize(node, new Node.Script(body)); - }; - // https://tc39.github.io/ecma262/#sec-imports - Parser.prototype.parseModuleSpecifier = function () { - var node = this.createNode(); - if (this.lookahead.type !== 8 /* StringLiteral */) { - this.throwError(messages_1.Messages.InvalidModuleSpecifier); - } - var token = this.nextToken(); - var raw = this.getTokenRaw(token); - return this.finalize(node, new Node.Literal(token.value, raw)); - }; - // import {} ...; - Parser.prototype.parseImportSpecifier = function () { - var node = this.createNode(); - var imported; - var local; - if (this.lookahead.type === 3 /* Identifier */) { - imported = this.parseVariableIdentifier(); - local = imported; - if (this.matchContextualKeyword('as')) { - this.nextToken(); - local = this.parseVariableIdentifier(); - } - } - else { - imported = this.parseIdentifierName(); - local = imported; - if (this.matchContextualKeyword('as')) { - this.nextToken(); - local = this.parseVariableIdentifier(); - } - else { - this.throwUnexpectedToken(this.nextToken()); - } - } - return this.finalize(node, new Node.ImportSpecifier(local, imported)); - }; - // {foo, bar as bas} - Parser.prototype.parseNamedImports = function () { - this.expect('{'); - var specifiers = []; - while (!this.match('}')) { - specifiers.push(this.parseImportSpecifier()); - if (!this.match('}')) { - this.expect(','); - } - } - this.expect('}'); - return specifiers; - }; - // import ...; - Parser.prototype.parseImportDefaultSpecifier = function () { - var node = this.createNode(); - var local = this.parseIdentifierName(); - return this.finalize(node, new Node.ImportDefaultSpecifier(local)); - }; - // import <* as foo> ...; - Parser.prototype.parseImportNamespaceSpecifier = function () { - var node = this.createNode(); - this.expect('*'); - if (!this.matchContextualKeyword('as')) { - this.throwError(messages_1.Messages.NoAsAfterImportNamespace); - } - this.nextToken(); - var local = this.parseIdentifierName(); - return this.finalize(node, new Node.ImportNamespaceSpecifier(local)); - }; - Parser.prototype.parseImportDeclaration = function () { - if (this.context.inFunctionBody) { - this.throwError(messages_1.Messages.IllegalImportDeclaration); - } - var node = this.createNode(); - this.expectKeyword('import'); - var src; - var specifiers = []; - if (this.lookahead.type === 8 /* StringLiteral */) { - // import 'foo'; - src = this.parseModuleSpecifier(); - } - else { - if (this.match('{')) { - // import {bar} - specifiers = specifiers.concat(this.parseNamedImports()); - } - else if (this.match('*')) { - // import * as foo - specifiers.push(this.parseImportNamespaceSpecifier()); - } - else if (this.isIdentifierName(this.lookahead) && !this.matchKeyword('default')) { - // import foo - specifiers.push(this.parseImportDefaultSpecifier()); - if (this.match(',')) { - this.nextToken(); - if (this.match('*')) { - // import foo, * as foo - specifiers.push(this.parseImportNamespaceSpecifier()); - } - else if (this.match('{')) { - // import foo, {bar} - specifiers = specifiers.concat(this.parseNamedImports()); - } - else { - this.throwUnexpectedToken(this.lookahead); - } - } - } - else { - this.throwUnexpectedToken(this.nextToken()); - } - if (!this.matchContextualKeyword('from')) { - var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; - this.throwError(message, this.lookahead.value); - } - this.nextToken(); - src = this.parseModuleSpecifier(); - } - this.consumeSemicolon(); - return this.finalize(node, new Node.ImportDeclaration(specifiers, src)); - }; - // https://tc39.github.io/ecma262/#sec-exports - Parser.prototype.parseExportSpecifier = function () { - var node = this.createNode(); - var local = this.parseIdentifierName(); - var exported = local; - if (this.matchContextualKeyword('as')) { - this.nextToken(); - exported = this.parseIdentifierName(); - } - return this.finalize(node, new Node.ExportSpecifier(local, exported)); - }; - Parser.prototype.parseExportDeclaration = function () { - if (this.context.inFunctionBody) { - this.throwError(messages_1.Messages.IllegalExportDeclaration); - } - var node = this.createNode(); - this.expectKeyword('export'); - var exportDeclaration; - if (this.matchKeyword('default')) { - // export default ... - this.nextToken(); - if (this.matchKeyword('function')) { - // export default function foo () {} - // export default function () {} - var declaration = this.parseFunctionDeclaration(true); - exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); - } - else if (this.matchKeyword('class')) { - // export default class foo {} - var declaration = this.parseClassDeclaration(true); - exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); - } - else if (this.matchContextualKeyword('async')) { - // export default async function f () {} - // export default async function () {} - // export default async x => x - var declaration = this.matchAsyncFunction() ? this.parseFunctionDeclaration(true) : this.parseAssignmentExpression(); - exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); - } - else { - if (this.matchContextualKeyword('from')) { - this.throwError(messages_1.Messages.UnexpectedToken, this.lookahead.value); - } - // export default {}; - // export default []; - // export default (1 + 2); - var declaration = this.match('{') ? this.parseObjectInitializer() : - this.match('[') ? this.parseArrayInitializer() : this.parseAssignmentExpression(); - this.consumeSemicolon(); - exportDeclaration = this.finalize(node, new Node.ExportDefaultDeclaration(declaration)); - } - } - else if (this.match('*')) { - // export * from 'foo'; - this.nextToken(); - if (!this.matchContextualKeyword('from')) { - var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; - this.throwError(message, this.lookahead.value); - } - this.nextToken(); - var src = this.parseModuleSpecifier(); - this.consumeSemicolon(); - exportDeclaration = this.finalize(node, new Node.ExportAllDeclaration(src)); - } - else if (this.lookahead.type === 4 /* Keyword */) { - // export var f = 1; - var declaration = void 0; - switch (this.lookahead.value) { - case 'let': - case 'const': - declaration = this.parseLexicalDeclaration({ inFor: false }); - break; - case 'var': - case 'class': - case 'function': - declaration = this.parseStatementListItem(); - break; - default: - this.throwUnexpectedToken(this.lookahead); - } - exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); - } - else if (this.matchAsyncFunction()) { - var declaration = this.parseFunctionDeclaration(); - exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(declaration, [], null)); - } - else { - var specifiers = []; - var source = null; - var isExportFromIdentifier = false; - this.expect('{'); - while (!this.match('}')) { - isExportFromIdentifier = isExportFromIdentifier || this.matchKeyword('default'); - specifiers.push(this.parseExportSpecifier()); - if (!this.match('}')) { - this.expect(','); - } - } - this.expect('}'); - if (this.matchContextualKeyword('from')) { - // export {default} from 'foo'; - // export {foo} from 'foo'; - this.nextToken(); - source = this.parseModuleSpecifier(); - this.consumeSemicolon(); - } - else if (isExportFromIdentifier) { - // export {default}; // missing fromClause - var message = this.lookahead.value ? messages_1.Messages.UnexpectedToken : messages_1.Messages.MissingFromClause; - this.throwError(message, this.lookahead.value); - } - else { - // export {foo}; - this.consumeSemicolon(); - } - exportDeclaration = this.finalize(node, new Node.ExportNamedDeclaration(null, specifiers, source)); - } - return exportDeclaration; - }; - return Parser; - }()); - exports.Parser = Parser; - - -/***/ }, -/* 9 */ -/***/ function(module, exports) { - - "use strict"; - // Ensure the condition is true, otherwise throw an error. - // This is only to have a better contract semantic, i.e. another safety net - // to catch a logic error. The condition shall be fulfilled in normal case. - // Do NOT use this to enforce a certain condition on any user input. - Object.defineProperty(exports, "__esModule", { value: true }); - function assert(condition, message) { - /* istanbul ignore if */ - if (!condition) { - throw new Error('ASSERT: ' + message); - } - } - exports.assert = assert; - - -/***/ }, -/* 10 */ -/***/ function(module, exports) { - - "use strict"; - /* tslint:disable:max-classes-per-file */ - Object.defineProperty(exports, "__esModule", { value: true }); - var ErrorHandler = (function () { - function ErrorHandler() { - this.errors = []; - this.tolerant = false; - } - ErrorHandler.prototype.recordError = function (error) { - this.errors.push(error); - }; - ErrorHandler.prototype.tolerate = function (error) { - if (this.tolerant) { - this.recordError(error); - } - else { - throw error; - } - }; - ErrorHandler.prototype.constructError = function (msg, column) { - var error = new Error(msg); - try { - throw error; - } - catch (base) { - /* istanbul ignore else */ - if (Object.create && Object.defineProperty) { - error = Object.create(base); - Object.defineProperty(error, 'column', { value: column }); - } - } - /* istanbul ignore next */ - return error; - }; - ErrorHandler.prototype.createError = function (index, line, col, description) { - var msg = 'Line ' + line + ': ' + description; - var error = this.constructError(msg, col); - error.index = index; - error.lineNumber = line; - error.description = description; - return error; - }; - ErrorHandler.prototype.throwError = function (index, line, col, description) { - throw this.createError(index, line, col, description); - }; - ErrorHandler.prototype.tolerateError = function (index, line, col, description) { - var error = this.createError(index, line, col, description); - if (this.tolerant) { - this.recordError(error); - } - else { - throw error; - } - }; - return ErrorHandler; - }()); - exports.ErrorHandler = ErrorHandler; - - -/***/ }, -/* 11 */ -/***/ function(module, exports) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - // Error messages should be identical to V8. - exports.Messages = { - BadGetterArity: 'Getter must not have any formal parameters', - BadSetterArity: 'Setter must have exactly one formal parameter', - BadSetterRestParameter: 'Setter function argument must not be a rest parameter', - ConstructorIsAsync: 'Class constructor may not be an async method', - ConstructorSpecialMethod: 'Class constructor may not be an accessor', - DeclarationMissingInitializer: 'Missing initializer in %0 declaration', - DefaultRestParameter: 'Unexpected token =', - DuplicateBinding: 'Duplicate binding %0', - DuplicateConstructor: 'A class may only have one constructor', - DuplicateProtoProperty: 'Duplicate __proto__ fields are not allowed in object literals', - ForInOfLoopInitializer: '%0 loop variable declaration may not have an initializer', - GeneratorInLegacyContext: 'Generator declarations are not allowed in legacy contexts', - IllegalBreak: 'Illegal break statement', - IllegalContinue: 'Illegal continue statement', - IllegalExportDeclaration: 'Unexpected token', - IllegalImportDeclaration: 'Unexpected token', - IllegalLanguageModeDirective: 'Illegal \'use strict\' directive in function with non-simple parameter list', - IllegalReturn: 'Illegal return statement', - InvalidEscapedReservedWord: 'Keyword must not contain escaped characters', - InvalidHexEscapeSequence: 'Invalid hexadecimal escape sequence', - InvalidLHSInAssignment: 'Invalid left-hand side in assignment', - InvalidLHSInForIn: 'Invalid left-hand side in for-in', - InvalidLHSInForLoop: 'Invalid left-hand side in for-loop', - InvalidModuleSpecifier: 'Unexpected token', - InvalidRegExp: 'Invalid regular expression', - LetInLexicalBinding: 'let is disallowed as a lexically bound name', - MissingFromClause: 'Unexpected token', - MultipleDefaultsInSwitch: 'More than one default clause in switch statement', - NewlineAfterThrow: 'Illegal newline after throw', - NoAsAfterImportNamespace: 'Unexpected token', - NoCatchOrFinally: 'Missing catch or finally after try', - ParameterAfterRestParameter: 'Rest parameter must be last formal parameter', - Redeclaration: '%0 \'%1\' has already been declared', - StaticPrototype: 'Classes may not have static property named prototype', - StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', - StrictDelete: 'Delete of an unqualified identifier in strict mode.', - StrictFunction: 'In strict mode code, functions can only be declared at top level or inside a block', - StrictFunctionName: 'Function name may not be eval or arguments in strict mode', - StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', - StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', - StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', - StrictModeWith: 'Strict mode code may not include a with statement', - StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', - StrictParamDupe: 'Strict mode function may not have duplicate parameter names', - StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', - StrictReservedWord: 'Use of future reserved word in strict mode', - StrictVarName: 'Variable name may not be eval or arguments in strict mode', - TemplateOctalLiteral: 'Octal literals are not allowed in template strings.', - UnexpectedEOS: 'Unexpected end of input', - UnexpectedIdentifier: 'Unexpected identifier', - UnexpectedNumber: 'Unexpected number', - UnexpectedReserved: 'Unexpected reserved word', - UnexpectedString: 'Unexpected string', - UnexpectedTemplate: 'Unexpected quasi %0', - UnexpectedToken: 'Unexpected token %0', - UnexpectedTokenIllegal: 'Unexpected token ILLEGAL', - UnknownLabel: 'Undefined label \'%0\'', - UnterminatedRegExp: 'Invalid regular expression: missing /' - }; - - -/***/ }, -/* 12 */ -/***/ function(module, exports, __webpack_require__) { - - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var assert_1 = __webpack_require__(9); - var character_1 = __webpack_require__(4); - var messages_1 = __webpack_require__(11); - function hexValue(ch) { - return '0123456789abcdef'.indexOf(ch.toLowerCase()); - } - function octalValue(ch) { - return '01234567'.indexOf(ch); - } - var Scanner = (function () { - function Scanner(code, handler) { - this.source = code; - this.errorHandler = handler; - this.trackComment = false; - this.isModule = false; - this.length = code.length; - this.index = 0; - this.lineNumber = (code.length > 0) ? 1 : 0; - this.lineStart = 0; - this.curlyStack = []; - } - Scanner.prototype.saveState = function () { - return { - index: this.index, - lineNumber: this.lineNumber, - lineStart: this.lineStart - }; - }; - Scanner.prototype.restoreState = function (state) { - this.index = state.index; - this.lineNumber = state.lineNumber; - this.lineStart = state.lineStart; - }; - Scanner.prototype.eof = function () { - return this.index >= this.length; - }; - Scanner.prototype.throwUnexpectedToken = function (message) { - if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } - return this.errorHandler.throwError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); - }; - Scanner.prototype.tolerateUnexpectedToken = function (message) { - if (message === void 0) { message = messages_1.Messages.UnexpectedTokenIllegal; } - this.errorHandler.tolerateError(this.index, this.lineNumber, this.index - this.lineStart + 1, message); - }; - // https://tc39.github.io/ecma262/#sec-comments - Scanner.prototype.skipSingleLineComment = function (offset) { - var comments = []; - var start, loc; - if (this.trackComment) { - comments = []; - start = this.index - offset; - loc = { - start: { - line: this.lineNumber, - column: this.index - this.lineStart - offset - }, - end: {} - }; - } - while (!this.eof()) { - var ch = this.source.charCodeAt(this.index); - ++this.index; - if (character_1.Character.isLineTerminator(ch)) { - if (this.trackComment) { - loc.end = { - line: this.lineNumber, - column: this.index - this.lineStart - 1 - }; - var entry = { - multiLine: false, - slice: [start + offset, this.index - 1], - range: [start, this.index - 1], - loc: loc - }; - comments.push(entry); - } - if (ch === 13 && this.source.charCodeAt(this.index) === 10) { - ++this.index; - } - ++this.lineNumber; - this.lineStart = this.index; - return comments; - } - } - if (this.trackComment) { - loc.end = { - line: this.lineNumber, - column: this.index - this.lineStart - }; - var entry = { - multiLine: false, - slice: [start + offset, this.index], - range: [start, this.index], - loc: loc - }; - comments.push(entry); - } - return comments; - }; - Scanner.prototype.skipMultiLineComment = function () { - var comments = []; - var start, loc; - if (this.trackComment) { - comments = []; - start = this.index - 2; - loc = { - start: { - line: this.lineNumber, - column: this.index - this.lineStart - 2 - }, - end: {} - }; - } - while (!this.eof()) { - var ch = this.source.charCodeAt(this.index); - if (character_1.Character.isLineTerminator(ch)) { - if (ch === 0x0D && this.source.charCodeAt(this.index + 1) === 0x0A) { - ++this.index; - } - ++this.lineNumber; - ++this.index; - this.lineStart = this.index; - } - else if (ch === 0x2A) { - // Block comment ends with '*/'. - if (this.source.charCodeAt(this.index + 1) === 0x2F) { - this.index += 2; - if (this.trackComment) { - loc.end = { - line: this.lineNumber, - column: this.index - this.lineStart - }; - var entry = { - multiLine: true, - slice: [start + 2, this.index - 2], - range: [start, this.index], - loc: loc - }; - comments.push(entry); - } - return comments; - } - ++this.index; - } - else { - ++this.index; - } - } - // Ran off the end of the file - the whole thing is a comment - if (this.trackComment) { - loc.end = { - line: this.lineNumber, - column: this.index - this.lineStart - }; - var entry = { - multiLine: true, - slice: [start + 2, this.index], - range: [start, this.index], - loc: loc - }; - comments.push(entry); - } - this.tolerateUnexpectedToken(); - return comments; - }; - Scanner.prototype.scanComments = function () { - var comments; - if (this.trackComment) { - comments = []; - } - var start = (this.index === 0); - while (!this.eof()) { - var ch = this.source.charCodeAt(this.index); - if (character_1.Character.isWhiteSpace(ch)) { - ++this.index; - } - else if (character_1.Character.isLineTerminator(ch)) { - ++this.index; - if (ch === 0x0D && this.source.charCodeAt(this.index) === 0x0A) { - ++this.index; - } - ++this.lineNumber; - this.lineStart = this.index; - start = true; - } - else if (ch === 0x2F) { - ch = this.source.charCodeAt(this.index + 1); - if (ch === 0x2F) { - this.index += 2; - var comment = this.skipSingleLineComment(2); - if (this.trackComment) { - comments = comments.concat(comment); - } - start = true; - } - else if (ch === 0x2A) { - this.index += 2; - var comment = this.skipMultiLineComment(); - if (this.trackComment) { - comments = comments.concat(comment); - } - } - else { - break; - } - } - else if (start && ch === 0x2D) { - // U+003E is '>' - if ((this.source.charCodeAt(this.index + 1) === 0x2D) && (this.source.charCodeAt(this.index + 2) === 0x3E)) { - // '-->' is a single-line comment - this.index += 3; - var comment = this.skipSingleLineComment(3); - if (this.trackComment) { - comments = comments.concat(comment); - } - } - else { - break; - } - } - else if (ch === 0x3C && !this.isModule) { - if (this.source.slice(this.index + 1, this.index + 4) === '!--') { - this.index += 4; // ` - Req; -server_authorization_check(#httpd{path_parts = [<<"_node">>, _, <<"_stats">> | _]} = Req) -> - require_metrics(Req); -server_authorization_check(#httpd{path_parts = [<<"_node">>, _, <<"_system">> | _]} = Req) -> - require_metrics(Req); -server_authorization_check(#httpd{path_parts = [<<"_node">>, _, <<"_prometheus">> | _]} = Req) -> - require_metrics(Req); -server_authorization_check(#httpd{path_parts = [<<"_", _/binary>> | _]} = Req) -> - require_admin(Req). - -db_authorization_check(#httpd{path_parts = [DbName | _], user_ctx = Ctx} = Req) -> - {_} = fabric:get_security(DbName, [{user_ctx, Ctx}]), - Req. - -require_metrics(#httpd{user_ctx = #user_ctx{roles = UserRoles}} = Req) -> - IsAdmin = lists:member(<<"_admin">>, UserRoles), - IsMetrics = lists:member(<<"_metrics">>, UserRoles), - case {IsAdmin, IsMetrics} of - {true, _} -> Req; - {_, true} -> Req; - _ -> throw({unauthorized, <<"You are not a server admin or read-only metrics user">>}) - end. - -require_admin(Req) -> - ok = couch_httpd:verify_is_server_admin(Req), - Req. - -require_db_admin(#httpd{path_parts = [DbName | _], user_ctx = Ctx} = Req) -> - Sec = fabric:get_security(DbName, [{user_ctx, Ctx}]), - - case is_db_admin(Ctx, Sec) of - true -> Req; - false -> throw({unauthorized, <<"You are not a server or db admin.">>}) - end. - -is_db_admin(#user_ctx{name = UserName, roles = UserRoles}, {Security}) -> - {Admins} = couch_util:get_value(<<"admins">>, Security, {[]}), - Names = couch_util:get_value(<<"names">>, Admins, []), - Roles = couch_util:get_value(<<"roles">>, Admins, []), - case check_security(roles, UserRoles, [<<"_admin">> | Roles]) of - true -> true; - false -> check_security(names, UserName, Names) - end. - -check_security(roles, [], _) -> - false; -check_security(roles, UserRoles, Roles) -> - UserRolesSet = ordsets:from_list(UserRoles), - RolesSet = ordsets:from_list(Roles), - not ordsets:is_disjoint(UserRolesSet, RolesSet); -check_security(names, _, []) -> - false; -check_security(names, null, _) -> - false; -check_security(names, UserName, Names) -> - lists:member(UserName, Names). diff --git a/src/chttpd/src/chttpd_cors.erl b/src/chttpd/src/chttpd_cors.erl deleted file mode 100644 index 70d3163ec..000000000 --- a/src/chttpd/src/chttpd_cors.erl +++ /dev/null @@ -1,414 +0,0 @@ -% 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. - --module(chttpd_cors). - --export([ - maybe_handle_preflight_request/1, - maybe_handle_preflight_request/2, - headers/2, - headers/4 -]). --export([ - is_cors_enabled/1, - get_cors_config/1 -]). - --include_lib("couch/include/couch_db.hrl"). --include_lib("chttpd/include/chttpd_cors.hrl"). - -%% http://www.w3.org/TR/cors/#resource-preflight-requests - -maybe_handle_preflight_request(#httpd{method = Method}) when Method /= 'OPTIONS' -> - not_preflight; -maybe_handle_preflight_request(Req) -> - case maybe_handle_preflight_request(Req, get_cors_config(Req)) of - not_preflight -> - not_preflight; - {ok, PreflightHeaders} -> - chttpd:send_response_no_cors(Req, 204, PreflightHeaders, <<>>) - end. - -maybe_handle_preflight_request(#httpd{} = Req, Config) -> - case is_cors_enabled(Config) of - true -> - case preflight_request(Req, Config) of - {ok, PreflightHeaders} -> - {ok, PreflightHeaders}; - not_preflight -> - not_preflight; - UnknownError -> - couch_log:error( - "Unknown response of chttpd_cors:preflight_request(~p): ~p", - [Req, UnknownError] - ), - not_preflight - end; - false -> - not_preflight - end. - -preflight_request(Req, Config) -> - case get_origin(Req) of - undefined -> - %% If the Origin header is not present terminate this set of - %% steps. The request is outside the scope of this specification. - %% http://www.w3.org/TR/cors/#resource-preflight-requests - not_preflight; - Origin -> - AcceptedOrigins = get_accepted_origins(Req, Config), - AcceptAll = lists:member(<<"*">>, AcceptedOrigins), - - HandlerFun = fun() -> - handle_preflight_request(Req, Config, Origin) - end, - - %% We either need to accept all origins or have it listed - %% in our origins. Origin can only contain a single origin - %% as the user agent will not follow redirects [1]. If the - %% value of the Origin header is not a case-sensitive - %% match for any of the values in list of origins do not - %% set any additional headers and terminate this set - %% of steps [1]. - %% - %% [1]: http://www.w3.org/TR/cors/#resource-preflight-requests - %% - %% TODO: Square against multi origin Security Considerations and the - %% Vary header - %% - case AcceptAll orelse lists:member(Origin, AcceptedOrigins) of - true -> HandlerFun(); - false -> not_preflight - end - end. - -handle_preflight_request(Req, Config, Origin) -> - case chttpd:header_value(Req, "Access-Control-Request-Method") of - undefined -> - %% If there is no Access-Control-Request-Method header - %% or if parsing failed, do not set any additional headers - %% and terminate this set of steps. The request is outside - %% the scope of this specification. - %% http://www.w3.org/TR/cors/#resource-preflight-requests - not_preflight; - Method -> - SupportedMethods = get_origin_config( - Config, - Origin, - <<"allow_methods">>, - ?SUPPORTED_METHODS - ), - - SupportedHeaders = get_origin_config( - Config, - Origin, - <<"allow_headers">>, - ?SUPPORTED_HEADERS - ), - - %% get max age - MaxAge = couch_util:get_value( - <<"max_age">>, - Config, - ?CORS_DEFAULT_MAX_AGE - ), - - PreflightHeaders0 = maybe_add_credentials(Config, Origin, [ - {"Access-Control-Allow-Origin", binary_to_list(Origin)}, - {"Access-Control-Max-Age", MaxAge}, - {"Access-Control-Allow-Methods", string:join(SupportedMethods, ", ")} - ]), - - case lists:member(Method, SupportedMethods) of - true -> - %% method ok , check headers - AccessHeaders = chttpd:header_value( - Req, - "Access-Control-Request-Headers" - ), - {FinalReqHeaders, ReqHeaders} = - case AccessHeaders of - undefined -> - {"", []}; - "" -> - {"", []}; - Headers -> - %% transform header list in something we - %% could check. make sure everything is a - %% list - RH = [ - to_lower(H) - || H <- split_headers(Headers) - ], - {Headers, RH} - end, - %% check if headers are supported - case ReqHeaders -- SupportedHeaders of - [] -> - PreflightHeaders = - PreflightHeaders0 ++ - [{"Access-Control-Allow-Headers", FinalReqHeaders}], - {ok, PreflightHeaders}; - _ -> - not_preflight - end; - false -> - %% If method is not a case-sensitive match for any of - %% the values in list of methods do not set any additional - %% headers and terminate this set of steps. - %% http://www.w3.org/TR/cors/#resource-preflight-requests - not_preflight - end - end. - -headers(Req, RequestHeaders) -> - case get_origin(Req) of - undefined -> - %% If the Origin header is not present terminate - %% this set of steps. The request is outside the scope - %% of this specification. - %% http://www.w3.org/TR/cors/#resource-processing-model - RequestHeaders; - Origin -> - headers(Req, RequestHeaders, Origin, get_cors_config(Req)) - end. - -headers(_Req, RequestHeaders, undefined, _Config) -> - RequestHeaders; -headers(Req, RequestHeaders, Origin, Config) when is_list(Origin) -> - headers(Req, RequestHeaders, ?l2b(string:to_lower(Origin)), Config); -headers(Req, RequestHeaders, Origin, Config) -> - case is_cors_enabled(Config) of - true -> - AcceptedOrigins = get_accepted_origins(Req, Config), - CorsHeaders = handle_headers(Config, Origin, AcceptedOrigins), - ExposedCouchHeaders = couch_util:get_value( - <<"exposed_headers">>, Config, ?COUCH_HEADERS - ), - maybe_apply_headers(CorsHeaders, RequestHeaders, ExposedCouchHeaders); - false -> - RequestHeaders - end. - -maybe_apply_headers([], RequestHeaders, _ExposedCouchHeaders) -> - RequestHeaders; -maybe_apply_headers(CorsHeaders, RequestHeaders, ExposedCouchHeaders) -> - %% Find all non ?SIMPLE_HEADERS and and non ?SIMPLE_CONTENT_TYPE_VALUES, - %% expose those through Access-Control-Expose-Headers, allowing - %% the client to access them in the browser. Also append in - %% ?COUCH_HEADERS, as further headers may be added later that - %% need to be exposed. - %% return: RequestHeaders ++ CorsHeaders ++ ACEH - - ExposedHeaders0 = simple_headers([K || {K, _V} <- RequestHeaders]), - - %% If Content-Type is not in ExposedHeaders, and the Content-Type - %% is not a member of ?SIMPLE_CONTENT_TYPE_VALUES, then add it - %% into the list of ExposedHeaders - ContentType = proplists:get_value("content-type", ExposedHeaders0), - IncludeContentType = - case ContentType of - undefined -> - false; - _ -> - lists:member(string:to_lower(ContentType), ?SIMPLE_CONTENT_TYPE_VALUES) - end, - ExposedHeaders = - case IncludeContentType of - false -> - ["content-type" | lists:delete("content-type", ExposedHeaders0)]; - true -> - ExposedHeaders0 - end, - - %% ExposedCouchHeaders may get added later, so expose them by default - ACEH = [ - {"Access-Control-Expose-Headers", string:join(ExposedHeaders ++ ExposedCouchHeaders, ", ")} - ], - CorsHeaders ++ RequestHeaders ++ ACEH. - -simple_headers(Headers) -> - LCHeaders = [to_lower(H) || H <- Headers], - lists:filter(fun(H) -> lists:member(H, ?SIMPLE_HEADERS) end, LCHeaders). - -to_lower(String) when is_binary(String) -> - to_lower(?b2l(String)); -to_lower(String) -> - string:to_lower(String). - -handle_headers(_Config, _Origin, []) -> - []; -handle_headers(Config, Origin, AcceptedOrigins) -> - AcceptAll = lists:member(<<"*">>, AcceptedOrigins), - case AcceptAll orelse lists:member(Origin, AcceptedOrigins) of - true -> - make_cors_header(Config, Origin); - false -> - %% If the value of the Origin header is not a - %% case-sensitive match for any of the values - %% in list of origins, do not set any additional - %% headers and terminate this set of steps. - %% http://www.w3.org/TR/cors/#resource-requests - [] - end. - -make_cors_header(Config, Origin) -> - Headers = [{"Access-Control-Allow-Origin", binary_to_list(Origin)}], - maybe_add_credentials(Config, Origin, Headers). - -%% util - -maybe_add_credentials(Config, Origin, Headers) -> - case allow_credentials(Config, Origin) of - false -> - Headers; - true -> - Headers ++ [{"Access-Control-Allow-Credentials", "true"}] - end. - -allow_credentials(_Config, <<"*">>) -> - false; -allow_credentials(Config, Origin) -> - get_origin_config( - Config, - Origin, - <<"allow_credentials">>, - ?CORS_DEFAULT_ALLOW_CREDENTIALS - ). - -get_cors_config(#httpd{cors_config = undefined, mochi_req = MochiReq}) -> - Host = couch_httpd_vhost:host(MochiReq), - - EnableCors = chttpd_util:get_chttpd_config_boolean("enable_cors", false), - AllowCredentials = cors_config(Host, "credentials", "false") =:= "true", - - AllowHeaders = - case cors_config(Host, "headers", undefined) of - undefined -> - ?SUPPORTED_HEADERS; - AllowHeaders0 -> - [to_lower(H) || H <- split_list(AllowHeaders0)] - end, - AllowMethods = - case cors_config(Host, "methods", undefined) of - undefined -> - ?SUPPORTED_METHODS; - AllowMethods0 -> - split_list(AllowMethods0) - end, - ExposedHeaders = - case cors_config(Host, "exposed_headers", undefined) of - undefined -> - ?COUCH_HEADERS; - ExposedHeaders0 -> - [to_lower(H) || H <- split_list(ExposedHeaders0)] - end, - MaxAge = cors_config(Host, "max_age", ?CORS_DEFAULT_MAX_AGE), - Origins0 = binary_split_list(cors_config(Host, "origins", [])), - Origins = [{O, {[]}} || O <- Origins0], - [ - {<<"enable_cors">>, EnableCors}, - {<<"allow_credentials">>, AllowCredentials}, - {<<"allow_methods">>, AllowMethods}, - {<<"allow_headers">>, AllowHeaders}, - {<<"exposed_headers">>, ExposedHeaders}, - {<<"max_age">>, MaxAge}, - {<<"origins">>, {Origins}} - ]; -get_cors_config(#httpd{cors_config = Config}) -> - Config. - -cors_config(Host, Key, Default) -> - config:get( - cors_section(Host), - Key, - config:get("cors", Key, Default) - ). - -cors_section(HostValue) -> - HostPort = maybe_strip_scheme(HostValue), - Host = hd(string:tokens(HostPort, ":")), - "cors:" ++ Host. - -maybe_strip_scheme(Host) -> - case string:str(Host, "://") of - 0 -> Host; - N -> string:substr(Host, N + 3) - end. - -is_cors_enabled(Config) -> - case get(disable_couch_httpd_cors) of - undefined -> - put(disable_couch_httpd_cors, true); - _ -> - ok - end, - couch_util:get_value(<<"enable_cors">>, Config, false). - -%% Get a list of {Origin, OriginConfig} tuples -%% ie: get_origin_configs(Config) -> -%% [ -%% {<<"http://foo.com">>, -%% { -%% [ -%% {<<"allow_credentials">>, true}, -%% {<<"allow_methods">>, [<<"POST">>]} -%% ] -%% } -%% }, -%% {<<"http://baz.com">>, {[]}} -%% ] -get_origin_configs(Config) -> - {Origins} = couch_util:get_value(<<"origins">>, Config, {[]}), - Origins. - -%% Get config for an individual Origin -%% ie: get_origin_config(Config, <<"http://foo.com">>) -> -%% [ -%% {<<"allow_credentials">>, true}, -%% {<<"allow_methods">>, [<<"POST">>]} -%% ] -get_origin_config(Config, Origin) -> - OriginConfigs = get_origin_configs(Config), - {OriginConfig} = couch_util:get_value(Origin, OriginConfigs, {[]}), - OriginConfig. - -%% Get config of a single key for an individual Origin -%% ie: get_origin_config(Config, <<"http://foo.com">>, <<"allow_methods">>, []) -%% [<<"POST">>] -get_origin_config(Config, Origin, Key, Default) -> - OriginConfig = get_origin_config(Config, Origin), - couch_util:get_value( - Key, - OriginConfig, - couch_util:get_value(Key, Config, Default) - ). - -get_origin(Req) -> - case chttpd:header_value(Req, "Origin") of - undefined -> - undefined; - Origin -> - ?l2b(Origin) - end. - -get_accepted_origins(_Req, Config) -> - lists:map(fun({K, _V}) -> K end, get_origin_configs(Config)). - -split_list(S) -> - re:split(S, "\\s*,\\s*", [trim, {return, list}]). - -binary_split_list(S) -> - [list_to_binary(E) || E <- split_list(S)]. - -split_headers(H) -> - re:split(H, ",\\s*", [{return, list}, trim]). diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl deleted file mode 100644 index 4392df194..000000000 --- a/src/chttpd/src/chttpd_db.erl +++ /dev/null @@ -1,2696 +0,0 @@ -% 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. - --module(chttpd_db). - --compile(tuple_calls). - --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). --include_lib("mem3/include/mem3.hrl"). - --export([ - handle_request/1, - handle_compact_req/2, - handle_design_req/2, - db_req/2, - couch_doc_open/4, - handle_changes_req/2, - update_doc_result_to_json/1, update_doc_result_to_json/2, - handle_design_info_req/3, - handle_view_cleanup_req/2, - update_doc/4, - http_code_from_status/1, - handle_partition_req/2 -]). - --import( - chttpd, - [ - send_json/2, send_json/3, send_json/4, - send_method_not_allowed/2, - start_json_response/2, - send_chunk/2, - end_json_response/1, - start_chunked_response/3, - absolute_uri/2, - send/2, - start_response_length/4 - ] -). - --record(doc_query_args, { - options = [], - rev = nil, - open_revs = [], - update_type = interactive_edit, - atts_since = nil -}). - -% Accumulator for changes_callback function --record(cacc, { - etag, - feed, - mochi, - prepend = "", - responding = false, - chunks_sent = 0, - buffer = [], - bufsize = 0, - threshold -}). - --define(IS_ALL_DOCS(T), - (T == <<"_all_docs">> orelse - T == <<"_local_docs">> orelse - T == <<"_design_docs">>) -). - --define(IS_MANGO(T), - (T == <<"_index">> orelse - T == <<"_find">> orelse - T == <<"_explain">>) -). - -% Database request handlers -handle_request(#httpd{path_parts = [DbName | RestParts], method = Method} = Req) -> - case {Method, RestParts} of - {'PUT', []} -> - create_db_req(Req, DbName); - {'DELETE', []} -> - % if we get ?rev=... the user is using a faulty script where the - % document id is empty by accident. Let them recover safely. - case chttpd:qs_value(Req, "rev", false) of - false -> - delete_db_req(Req, DbName); - _Rev -> - throw( - {bad_request, - "You tried to DELETE a database with a ?=rev parameter. " ++ - "Did you mean to DELETE a document instead?"} - ) - end; - {_, []} -> - do_db_req(Req, fun db_req/2); - {_, [SecondPart | _]} -> - Handler = chttpd_handlers:db_handler(SecondPart, fun db_req/2), - do_db_req(Req, Handler) - end. - -handle_changes_req(#httpd{method = 'POST'} = Req, Db) -> - chttpd:validate_ctype(Req, "application/json"), - case chttpd:body_length(Req) of - 0 -> - handle_changes_req1(Req, Db); - _ -> - {JsonProps} = chttpd:json_body_obj(Req), - handle_changes_req1(Req#httpd{req_body = {JsonProps}}, Db) - end; -handle_changes_req(#httpd{method = 'GET'} = Req, Db) -> - handle_changes_req1(Req, Db); -handle_changes_req(#httpd{path_parts = [_, <<"_changes">>]} = Req, _Db) -> - send_method_not_allowed(Req, "GET,POST,HEAD"). - -handle_changes_req1(#httpd{} = Req, Db) -> - #changes_args{filter = Raw, style = Style} = Args0 = parse_changes_query(Req), - ChangesArgs = Args0#changes_args{ - filter_fun = couch_changes:configure_filter(Raw, Style, Req, Db), - db_open_options = [{user_ctx, couch_db:get_user_ctx(Db)}] - }, - Max = chttpd:chunked_response_buffer_size(), - case ChangesArgs#changes_args.feed of - "normal" -> - T0 = os:timestamp(), - {ok, Info} = fabric:get_db_info(Db), - Suffix = mem3:shard_suffix(Db), - Etag = chttpd:make_etag({Info, Suffix}), - DeltaT = timer:now_diff(os:timestamp(), T0) / 1000, - couch_stats:update_histogram([couchdb, dbinfo], DeltaT), - chttpd:etag_respond(Req, Etag, fun() -> - Acc0 = #cacc{ - feed = normal, - etag = Etag, - mochi = Req, - threshold = Max - }, - fabric:changes(Db, fun changes_callback/2, Acc0, ChangesArgs) - end); - Feed when Feed =:= "continuous"; Feed =:= "longpoll"; Feed =:= "eventsource" -> - couch_stats:increment_counter([couchdb, httpd, clients_requesting_changes]), - Acc0 = #cacc{ - feed = list_to_atom(Feed), - mochi = Req, - threshold = Max - }, - try - fabric:changes(Db, fun changes_callback/2, Acc0, ChangesArgs) - after - couch_stats:decrement_counter([couchdb, httpd, clients_requesting_changes]) - end; - _ -> - Msg = <<"Supported `feed` types: normal, continuous, live, longpoll, eventsource">>, - throw({bad_request, Msg}) - end. - -% callbacks for continuous feed (newline-delimited JSON Objects) -changes_callback(start, #cacc{feed = continuous} = Acc) -> - {ok, Resp} = chttpd:start_delayed_json_response(Acc#cacc.mochi, 200), - {ok, Acc#cacc{mochi = Resp, responding = true}}; -changes_callback({change, Change}, #cacc{feed = continuous} = Acc) -> - chttpd_stats:incr_rows(), - Data = [?JSON_ENCODE(Change) | "\n"], - Len = iolist_size(Data), - maybe_flush_changes_feed(Acc, Data, Len); -changes_callback({stop, EndSeq, Pending}, #cacc{feed = continuous} = Acc) -> - #cacc{mochi = Resp, buffer = Buf} = Acc, - Row = - {[ - {<<"last_seq">>, EndSeq}, - {<<"pending">>, Pending} - ]}, - Data = [Buf, ?JSON_ENCODE(Row) | "\n"], - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, Data), - chttpd:end_delayed_json_response(Resp1); -% callbacks for eventsource feed (newline-delimited eventsource Objects) -changes_callback(start, #cacc{feed = eventsource} = Acc) -> - #cacc{mochi = Req} = Acc, - Headers = [ - {"Content-Type", "text/event-stream"}, - {"Cache-Control", "no-cache"} - ], - {ok, Resp} = chttpd:start_delayed_json_response(Req, 200, Headers), - {ok, Acc#cacc{mochi = Resp, responding = true}}; -changes_callback({change, {ChangeProp} = Change}, #cacc{feed = eventsource} = Acc) -> - chttpd_stats:incr_rows(), - Seq = proplists:get_value(seq, ChangeProp), - Chunk = [ - "data: ", - ?JSON_ENCODE(Change), - "\n", - "id: ", - ?JSON_ENCODE(Seq), - "\n\n" - ], - Len = iolist_size(Chunk), - maybe_flush_changes_feed(Acc, Chunk, Len); -changes_callback(timeout, #cacc{feed = eventsource} = Acc) -> - #cacc{mochi = Resp, chunks_sent = ChunksSet} = Acc, - Chunk = "event: heartbeat\ndata: \n\n", - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, Chunk), - {ok, Acc#cacc{mochi = Resp1, chunks_sent = ChunksSet + 1}}; -changes_callback({stop, _EndSeq}, #cacc{feed = eventsource} = Acc) -> - #cacc{mochi = Resp, buffer = Buf} = Acc, - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, Buf), - chttpd:end_delayed_json_response(Resp1); -% callbacks for longpoll and normal (single JSON Object) -changes_callback(start, #cacc{feed = normal} = Acc) -> - #cacc{etag = Etag, mochi = Req} = Acc, - FirstChunk = "{\"results\":[\n", - {ok, Resp} = chttpd:start_delayed_json_response( - Req, - 200, - [{"ETag", Etag}], - FirstChunk - ), - {ok, Acc#cacc{mochi = Resp, responding = true}}; -changes_callback(start, Acc) -> - #cacc{mochi = Req} = Acc, - FirstChunk = "{\"results\":[\n", - {ok, Resp} = chttpd:start_delayed_json_response(Req, 200, [], FirstChunk), - {ok, Acc#cacc{mochi = Resp, responding = true}}; -changes_callback({change, Change}, Acc) -> - chttpd_stats:incr_rows(), - Data = [Acc#cacc.prepend, ?JSON_ENCODE(Change)], - Len = iolist_size(Data), - maybe_flush_changes_feed(Acc, Data, Len); -changes_callback({stop, EndSeq, Pending}, Acc) -> - #cacc{buffer = Buf, mochi = Resp, threshold = Max} = Acc, - Terminator = [ - "\n],\n\"last_seq\":", - ?JSON_ENCODE(EndSeq), - ",\"pending\":", - ?JSON_ENCODE(Pending), - "}\n" - ], - {ok, Resp1} = chttpd:close_delayed_json_object(Resp, Buf, Terminator, Max), - chttpd:end_delayed_json_response(Resp1); -changes_callback(waiting_for_updates, #cacc{buffer = []} = Acc) -> - #cacc{mochi = Resp, chunks_sent = ChunksSent} = Acc, - case ChunksSent > 0 of - true -> - {ok, Acc}; - false -> - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, <<"\n">>), - {ok, Acc#cacc{mochi = Resp1, chunks_sent = 1}} - end; -changes_callback(waiting_for_updates, Acc) -> - #cacc{buffer = Buf, mochi = Resp, chunks_sent = ChunksSent} = Acc, - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, Buf), - {ok, Acc#cacc{ - buffer = [], - bufsize = 0, - mochi = Resp1, - chunks_sent = ChunksSent + 1 - }}; -changes_callback(timeout, Acc) -> - #cacc{mochi = Resp, chunks_sent = ChunksSent} = Acc, - {ok, Resp1} = chttpd:send_delayed_chunk(Resp, "\n"), - {ok, Acc#cacc{mochi = Resp1, chunks_sent = ChunksSent + 1}}; -changes_callback({error, Reason}, #cacc{mochi = #httpd{}} = Acc) -> - #cacc{mochi = Req} = Acc, - chttpd:send_error(Req, Reason); -changes_callback({error, Reason}, #cacc{feed = normal, responding = false} = Acc) -> - #cacc{mochi = Req} = Acc, - chttpd:send_error(Req, Reason); -changes_callback({error, Reason}, Acc) -> - chttpd:send_delayed_error(Acc#cacc.mochi, Reason). - -maybe_flush_changes_feed(#cacc{bufsize = Size, threshold = Max} = Acc, Data, Len) when - Size > 0 andalso (Size + Len) > Max --> - #cacc{buffer = Buffer, mochi = Resp} = Acc, - {ok, R1} = chttpd:send_delayed_chunk(Resp, Buffer), - {ok, Acc#cacc{prepend = ",\r\n", buffer = Data, bufsize = Len, mochi = R1}}; -maybe_flush_changes_feed(Acc0, Data, Len) -> - #cacc{buffer = Buf, bufsize = Size, chunks_sent = ChunksSent} = Acc0, - Acc = Acc0#cacc{ - prepend = ",\r\n", - buffer = [Buf | Data], - bufsize = Size + Len, - chunks_sent = ChunksSent + 1 - }, - {ok, Acc}. - -handle_compact_req(#httpd{method = 'POST'} = Req, Db) -> - chttpd:validate_ctype(Req, "application/json"), - case Req#httpd.path_parts of - [_DbName, <<"_compact">>] -> - ok = fabric:compact(Db), - send_json(Req, 202, {[{ok, true}]}); - [DbName, <<"_compact">>, DesignName | _] -> - case ddoc_cache:open(DbName, <<"_design/", DesignName/binary>>) of - {ok, _DDoc} -> - ok = fabric:compact(Db, DesignName), - send_json(Req, 202, {[{ok, true}]}); - Error -> - throw(Error) - end - end; -handle_compact_req(Req, _Db) -> - send_method_not_allowed(Req, "POST"). - -handle_view_cleanup_req(Req, Db) -> - ok = fabric:cleanup_index_files_all_nodes(Db), - send_json(Req, 202, {[{ok, true}]}). - -handle_partition_req(#httpd{path_parts = [_, _]} = _Req, _Db) -> - throw({bad_request, invalid_partition_req}); -handle_partition_req(#httpd{method = 'GET', path_parts = [_, _, PartId]} = Req, Db) -> - couch_partition:validate_partition(PartId), - case couch_db:is_partitioned(Db) of - true -> - {ok, PartitionInfo} = fabric:get_partition_info(Db, PartId), - send_json(Req, {PartitionInfo}); - false -> - throw({bad_request, <<"database is not partitioned">>}) - end; -handle_partition_req( - #httpd{ - method = 'POST', - path_parts = [_, <<"_partition">>, <<"_", _/binary>>] - }, - _Db -) -> - Msg = <<"Partition must not start with an underscore">>, - throw({illegal_partition, Msg}); -handle_partition_req(#httpd{path_parts = [_, _, _]} = Req, _Db) -> - send_method_not_allowed(Req, "GET"); -handle_partition_req(#httpd{path_parts = [DbName, _, PartId | Rest]} = Req, Db) -> - case couch_db:is_partitioned(Db) of - true -> - couch_partition:validate_partition(PartId), - QS = chttpd:qs(Req), - PartIdStr = ?b2l(PartId), - QSPartIdStr = couch_util:get_value("partition", QS, PartIdStr), - if - QSPartIdStr == PartIdStr -> - ok; - true -> - Msg = <<"Conflicting value for `partition` in query string">>, - throw({bad_request, Msg}) - end, - NewQS = lists:ukeysort(1, [{"partition", PartIdStr} | QS]), - NewReq = Req#httpd{ - path_parts = [DbName | Rest], - qs = NewQS - }, - update_partition_stats(Rest), - case Rest of - [OP | _] when OP == <<"_all_docs">> orelse ?IS_MANGO(OP) -> - case chttpd_handlers:db_handler(OP, fun db_req/2) of - Handler when is_function(Handler, 2) -> - Handler(NewReq, Db); - _ -> - chttpd:send_error(Req, not_found) - end; - [<<"_design">>, _Name, <<"_", _/binary>> | _] -> - handle_design_req(NewReq, Db); - _ -> - chttpd:send_error(Req, not_found) - end; - false -> - throw({bad_request, <<"database is not partitioned">>}) - end; -handle_partition_req(Req, _Db) -> - chttpd:send_error(Req, not_found). - -update_partition_stats(PathParts) -> - case PathParts of - [<<"_design">> | _] -> - couch_stats:increment_counter([couchdb, httpd, partition_view_requests]); - [<<"_all_docs">> | _] -> - couch_stats:increment_counter([couchdb, httpd, partition_all_docs_requests]); - [<<"_find">> | _] -> - couch_stats:increment_counter([couchdb, httpd, partition_find_requests]); - [<<"_explain">> | _] -> - couch_stats:increment_counter([couchdb, httpd, partition_explain_requests]); - _ -> - % ignore path that do not match - ok - end. - -handle_design_req( - #httpd{ - path_parts = [_DbName, _Design, Name, <<"_", _/binary>> = Action | _Rest] - } = Req, - Db -) -> - DbName = mem3:dbname(couch_db:name(Db)), - case ddoc_cache:open(DbName, <<"_design/", Name/binary>>) of - {ok, DDoc} -> - Handler = chttpd_handlers:design_handler(Action, fun bad_action_req/3), - Handler(Req, Db, DDoc); - Error -> - throw(Error) - end; -handle_design_req(Req, Db) -> - db_req(Req, Db). - -bad_action_req(#httpd{path_parts = [_, _, Name | FileNameParts]} = Req, Db, _DDoc) -> - db_attachment_req(Req, Db, <<"_design/", Name/binary>>, FileNameParts). - -handle_design_info_req(#httpd{method = 'GET'} = Req, Db, #doc{} = DDoc) -> - [_, _, Name, _] = Req#httpd.path_parts, - {ok, GroupInfoList} = fabric:get_view_group_info(Db, DDoc), - send_json( - Req, - 200, - {[ - {name, Name}, - {view_index, {GroupInfoList}} - ]} - ); -handle_design_info_req(Req, _Db, _DDoc) -> - send_method_not_allowed(Req, "GET"). - -create_db_req(#httpd{} = Req, DbName) -> - couch_httpd:verify_is_server_admin(Req), - ShardsOpt = parse_shards_opt(Req), - EngineOpt = parse_engine_opt(Req), - DbProps = parse_partitioned_opt(Req), - Options = lists:append([ShardsOpt, [{props, DbProps}], EngineOpt]), - DocUrl = absolute_uri(Req, "/" ++ couch_util:url_encode(DbName)), - case fabric:create_db(DbName, Options) of - ok -> - send_json(Req, 201, [{"Location", DocUrl}], {[{ok, true}]}); - accepted -> - send_json(Req, 202, [{"Location", DocUrl}], {[{ok, true}]}); - {error, file_exists} -> - chttpd:send_error(Req, file_exists); - Error -> - throw(Error) - end. - -delete_db_req(#httpd{} = Req, DbName) -> - couch_httpd:verify_is_server_admin(Req), - case fabric:delete_db(DbName, []) of - ok -> - send_json(Req, 200, {[{ok, true}]}); - accepted -> - send_json(Req, 202, {[{ok, true}]}); - Error -> - throw(Error) - end. - -do_db_req(#httpd{path_parts = [DbName | _], user_ctx = Ctx} = Req, Fun) -> - Shard = hd(mem3:shards(DbName)), - Props = couch_util:get_value(props, Shard#shard.opts, []), - Opts = - case Ctx of - undefined -> - [{props, Props}]; - #user_ctx{} -> - [{user_ctx, Ctx}, {props, Props}] - end, - {ok, Db} = couch_db:clustered_db(DbName, Opts), - Fun(Req, Db). - -db_req(#httpd{method = 'GET', path_parts = [DbName]} = Req, _Db) -> - % measure the time required to generate the etag, see if it's worth it - T0 = os:timestamp(), - {ok, DbInfo} = fabric:get_db_info(DbName), - DeltaT = timer:now_diff(os:timestamp(), T0) / 1000, - couch_stats:update_histogram([couchdb, dbinfo], DeltaT), - send_json(Req, {DbInfo}); -db_req(#httpd{method = 'POST', path_parts = [DbName], user_ctx = Ctx} = Req, Db) -> - chttpd:validate_ctype(Req, "application/json"), - - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - Options = [{user_ctx, Ctx}, {w, W}], - - Doc = couch_db:doc_from_json_obj_validate(Db, chttpd:json_body(Req)), - validate_attachment_names(Doc), - Doc2 = - case Doc#doc.id of - <<"">> -> - Doc#doc{id = couch_uuids:new(), revs = {0, []}}; - _ -> - Doc - end, - DocId = Doc2#doc.id, - case chttpd:qs_value(Req, "batch") of - "ok" -> - % async_batching - spawn(fun() -> - case catch (fabric:update_doc(Db, Doc2, Options)) of - {ok, _} -> - chttpd_stats:incr_writes(), - ok; - {accepted, _} -> - chttpd_stats:incr_writes(), - ok; - Error -> - couch_log:debug("Batch doc error (~s): ~p", [DocId, Error]) - end - end), - - send_json( - Req, - 202, - [], - {[ - {ok, true}, - {id, DocId} - ]} - ); - _Normal -> - % normal - DocUrl = absolute_uri(Req, [ - $/, - couch_util:url_encode(DbName), - $/, - couch_util:url_encode(DocId) - ]), - case fabric:update_doc(Db, Doc2, Options) of - {ok, NewRev} -> - chttpd_stats:incr_writes(), - HttpCode = 201; - {accepted, NewRev} -> - chttpd_stats:incr_writes(), - HttpCode = 202 - end, - send_json( - Req, - HttpCode, - [{"Location", DocUrl}], - {[ - {ok, true}, - {id, DocId}, - {rev, couch_doc:rev_to_str(NewRev)} - ]} - ) - end; -db_req(#httpd{path_parts = [_DbName]} = Req, _Db) -> - send_method_not_allowed(Req, "DELETE,GET,HEAD,POST"); -db_req( - #httpd{ - method = 'POST', - path_parts = [DbName, <<"_ensure_full_commit">>], - user_ctx = Ctx - } = Req, - _Db -) -> - chttpd:validate_ctype(Req, "application/json"), - %% use fabric call to trigger a database_does_not_exist exception - %% for missing databases that'd return error 404 from chttpd - %% get_security used to prefer shards on the same node over other nodes - fabric:get_security(DbName, [{user_ctx, Ctx}]), - CreationTime = mem3:shard_creation_time(DbName), - send_json( - Req, - 201, - {[ - {ok, true}, - {instance_start_time, CreationTime} - ]} - ); -db_req(#httpd{path_parts = [_, <<"_ensure_full_commit">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req(#httpd{method = 'POST', path_parts = [_, <<"_bulk_docs">>], user_ctx = Ctx} = Req, Db) -> - couch_stats:increment_counter([couchdb, httpd, bulk_requests]), - chttpd:validate_ctype(Req, "application/json"), - {JsonProps} = chttpd:json_body_obj(Req), - DocsArray = - case couch_util:get_value(<<"docs">>, JsonProps) of - undefined -> - throw({bad_request, <<"POST body must include `docs` parameter.">>}); - DocsArray0 when not is_list(DocsArray0) -> - throw({bad_request, <<"`docs` parameter must be an array.">>}); - DocsArray0 -> - DocsArray0 - end, - couch_stats:update_histogram([couchdb, httpd, bulk_docs], length(DocsArray)), - W = - case couch_util:get_value(<<"w">>, JsonProps) of - Value when is_integer(Value) -> - integer_to_list(Value); - _ -> - chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))) - end, - case chttpd:header_value(Req, "X-Couch-Full-Commit") of - "true" -> - Options = [full_commit, {user_ctx, Ctx}, {w, W}]; - "false" -> - Options = [delay_commit, {user_ctx, Ctx}, {w, W}]; - _ -> - Options = [{user_ctx, Ctx}, {w, W}] - end, - NewEdits = couch_util:get_value(<<"new_edits">>, JsonProps, true), - Docs = lists:map( - fun(JsonObj) -> - Doc = couch_db:doc_from_json_obj_validate(Db, JsonObj), - validate_revs(Doc, NewEdits), - validate_attachment_names(Doc), - case Doc#doc.id of - <<>> -> Doc#doc{id = couch_uuids:new()}; - _ -> Doc - end - end, - DocsArray - ), - case NewEdits of - true -> - Options2 = - case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of - true -> [all_or_nothing | Options]; - _ -> Options - end, - case fabric:update_docs(Db, Docs, Options2) of - {ok, Results} -> - % output the results - chttpd_stats:incr_writes(length(Results)), - DocResults = lists:zipwith( - fun update_doc_result_to_json/2, - Docs, - Results - ), - send_json(Req, 201, DocResults); - {accepted, Results} -> - % output the results - chttpd_stats:incr_writes(length(Results)), - DocResults = lists:zipwith( - fun update_doc_result_to_json/2, - Docs, - Results - ), - send_json(Req, 202, DocResults); - {error, Results} -> - % output the results - chttpd_stats:incr_writes(length(Results)), - DocResults = lists:zipwith( - fun update_doc_result_to_json/2, - Docs, - Results - ), - send_json(Req, 500, DocResults); - {aborted, Errors} -> - ErrorsJson = - lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 417, ErrorsJson) - end; - false -> - case fabric:update_docs(Db, Docs, [replicated_changes | Options]) of - {ok, Errors} -> - chttpd_stats:incr_writes(length(Docs)), - ErrorsJson = lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 201, ErrorsJson); - {accepted, Errors} -> - chttpd_stats:incr_writes(length(Docs)), - ErrorsJson = lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 202, ErrorsJson); - {error, Errors} -> - chttpd_stats:incr_writes(length(Docs)), - ErrorsJson = lists:map(fun update_doc_result_to_json/1, Errors), - send_json(Req, 500, ErrorsJson) - end; - _ -> - throw({bad_request, <<"`new_edits` parameter must be a boolean.">>}) - end; -db_req(#httpd{path_parts = [_, <<"_bulk_docs">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req( - #httpd{ - method = 'POST', - path_parts = [_, <<"_bulk_get">>], - mochi_req = MochiReq - } = Req, - Db -) -> - couch_stats:increment_counter([couchdb, httpd, bulk_requests]), - couch_httpd:validate_ctype(Req, "application/json"), - {JsonProps} = chttpd:json_body_obj(Req), - case couch_util:get_value(<<"docs">>, JsonProps) of - undefined -> - throw({bad_request, <<"Missing JSON list of 'docs'.">>}); - Docs -> - #doc_query_args{ - options = Options0 - } = bulk_get_parse_doc_query(Req), - Options = [{user_ctx, Req#httpd.user_ctx} | Options0], - - AcceptJson = MochiReq:accepts_content_type("application/json"), - AcceptMixedMp = MochiReq:accepts_content_type("multipart/mixed"), - AcceptRelatedMp = MochiReq:accepts_content_type("multipart/related"), - AcceptMp = not AcceptJson andalso (AcceptMixedMp orelse AcceptRelatedMp), - case AcceptMp of - false -> - {ok, Resp} = start_json_response(Req, 200), - send_chunk(Resp, <<"{\"results\": [">>), - lists:foldl( - fun(Doc, Sep) -> - {DocId, Results, Options1} = bulk_get_open_doc_revs( - Db, - Doc, - Options - ), - bulk_get_send_docs_json(Resp, DocId, Results, Options1, Sep), - <<",">> - end, - <<"">>, - Docs - ), - send_chunk(Resp, <<"]}">>), - end_json_response(Resp); - true -> - OuterBoundary = bulk_get_multipart_boundary(), - MpType = - case AcceptMixedMp of - true -> - "multipart/mixed"; - _ -> - "multipart/related" - end, - CType = - {"Content-Type", - MpType ++ "; boundary=\"" ++ - ?b2l(OuterBoundary) ++ "\""}, - {ok, Resp} = start_chunked_response(Req, 200, [CType]), - lists:foldl( - fun(Doc, _Pre) -> - case bulk_get_open_doc_revs(Db, Doc, Options) of - {_, {ok, []}, _Options1} -> - ok; - {_, {ok, Results}, Options1} -> - send_docs_multipart_bulk_get( - Results, - Options1, - OuterBoundary, - Resp - ); - {DocId, {error, {RevId, Error, Reason}}, _Options1} -> - Json = ?JSON_ENCODE( - {[ - {<<"id">>, DocId}, - {<<"rev">>, RevId}, - {<<"error">>, Error}, - {<<"reason">>, Reason} - ]} - ), - couch_httpd:send_chunk(Resp, [ - <<"\r\n--", OuterBoundary/binary>>, - <<"\r\nContent-Type: application/json; error=\"true\"\r\n\r\n">>, - Json - ]) - end - end, - <<"">>, - Docs - ), - case Docs of - [] -> - ok; - _ -> - couch_httpd:send_chunk( - Resp, <<"\r\n", "--", OuterBoundary/binary, "--\r\n">> - ) - end, - couch_httpd:last_chunk(Resp) - end - end; -db_req(#httpd{path_parts = [_, <<"_bulk_get">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req(#httpd{method = 'POST', path_parts = [_, <<"_purge">>]} = Req, Db) -> - couch_stats:increment_counter([couchdb, httpd, purge_requests]), - chttpd:validate_ctype(Req, "application/json"), - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - Options = [{user_ctx, Req#httpd.user_ctx}, {w, W}], - {IdsRevs} = chttpd:json_body_obj(Req), - IdsRevs2 = [{Id, couch_doc:parse_revs(Revs)} || {Id, Revs} <- IdsRevs], - MaxIds = config:get_integer("purge", "max_document_id_number", 100), - case length(IdsRevs2) =< MaxIds of - false -> throw({bad_request, "Exceeded maximum number of documents."}); - true -> ok - end, - RevsLen = lists:foldl( - fun({_Id, Revs}, Acc) -> - length(Revs) + Acc - end, - 0, - IdsRevs2 - ), - MaxRevs = config:get_integer("purge", "max_revisions_number", 1000), - case RevsLen =< MaxRevs of - false -> throw({bad_request, "Exceeded maximum number of revisions."}); - true -> ok - end, - couch_stats:increment_counter([couchdb, document_purges, total], length(IdsRevs2)), - Results2 = - case fabric:purge_docs(Db, IdsRevs2, Options) of - {ok, Results} -> - chttpd_stats:incr_writes(length(Results)), - Results; - {accepted, Results} -> - chttpd_stats:incr_writes(length(Results)), - Results - end, - {Code, Json} = purge_results_to_json(IdsRevs2, Results2), - send_json(Req, Code, {[{<<"purge_seq">>, null}, {<<"purged">>, {Json}}]}); -db_req(#httpd{path_parts = [_, <<"_purge">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req(#httpd{method = 'GET', path_parts = [_, OP]} = Req, Db) when ?IS_ALL_DOCS(OP) -> - case chttpd:qs_json_value(Req, "keys", nil) of - Keys when is_list(Keys) -> - all_docs_view(Req, Db, Keys, OP); - nil -> - all_docs_view(Req, Db, undefined, OP); - _ -> - throw({bad_request, "`keys` parameter must be an array."}) - end; -db_req( - #httpd{ - method = 'POST', - path_parts = [_, OP, <<"queries">>] - } = Req, - Db -) when ?IS_ALL_DOCS(OP) -> - Props = chttpd:json_body_obj(Req), - case couch_mrview_util:get_view_queries(Props) of - undefined -> - throw({bad_request, <<"POST body must include `queries` parameter.">>}); - Queries -> - multi_all_docs_view(Req, Db, OP, Queries) - end; -db_req( - #httpd{path_parts = [_, OP, <<"queries">>]} = Req, - _Db -) when ?IS_ALL_DOCS(OP) -> - send_method_not_allowed(Req, "POST"); -db_req(#httpd{method = 'POST', path_parts = [_, OP]} = Req, Db) when ?IS_ALL_DOCS(OP) -> - chttpd:validate_ctype(Req, "application/json"), - {Fields} = chttpd:json_body_obj(Req), - case couch_util:get_value(<<"keys">>, Fields, nil) of - Keys when is_list(Keys) -> - all_docs_view(Req, Db, Keys, OP); - nil -> - all_docs_view(Req, Db, undefined, OP); - _ -> - throw({bad_request, "`keys` body member must be an array."}) - end; -db_req(#httpd{path_parts = [_, OP]} = Req, _Db) when ?IS_ALL_DOCS(OP) -> - send_method_not_allowed(Req, "GET,HEAD,POST"); -db_req(#httpd{method = 'POST', path_parts = [_, <<"_missing_revs">>]} = Req, Db) -> - chttpd:validate_ctype(Req, "application/json"), - {JsonDocIdRevs} = chttpd:json_body_obj(Req), - case fabric:get_missing_revs(Db, JsonDocIdRevs) of - {error, Reason} -> - chttpd:send_error(Req, Reason); - {ok, Results} -> - Results2 = [ - {Id, couch_doc:revs_to_strs(Revs)} - || {Id, Revs, _} <- Results - ], - send_json( - Req, - {[ - {missing_revs, {Results2}} - ]} - ) - end; -db_req(#httpd{path_parts = [_, <<"_missing_revs">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req(#httpd{method = 'POST', path_parts = [_, <<"_revs_diff">>]} = Req, Db) -> - chttpd:validate_ctype(Req, "application/json"), - {JsonDocIdRevs} = chttpd:json_body_obj(Req), - case fabric:get_missing_revs(Db, JsonDocIdRevs) of - {error, Reason} -> - chttpd:send_error(Req, Reason); - {ok, Results} -> - Results2 = - lists:map( - fun({Id, MissingRevs, PossibleAncestors}) -> - {Id, { - [{missing, couch_doc:revs_to_strs(MissingRevs)}] ++ - if - PossibleAncestors == [] -> - []; - true -> - [ - {possible_ancestors, - couch_doc:revs_to_strs(PossibleAncestors)} - ] - end - }} - end, - Results - ), - send_json(Req, {Results2}) - end; -db_req(#httpd{path_parts = [_, <<"_revs_diff">>]} = Req, _Db) -> - send_method_not_allowed(Req, "POST"); -db_req( - #httpd{method = 'PUT', path_parts = [_, <<"_security">>], user_ctx = Ctx} = Req, - Db -) -> - DbName = ?b2l(couch_db:name(Db)), - validate_security_can_be_edited(DbName), - SecObj = chttpd:json_body(Req), - case fabric:set_security(Db, SecObj, [{user_ctx, Ctx}]) of - ok -> - send_json(Req, {[{<<"ok">>, true}]}); - Else -> - throw(Else) - end; -db_req(#httpd{method = 'GET', path_parts = [_, <<"_security">>]} = Req, Db) -> - send_json(Req, fabric:get_security(Db)); -db_req(#httpd{path_parts = [_, <<"_security">>]} = Req, _Db) -> - send_method_not_allowed(Req, "PUT,GET"); -db_req( - #httpd{method = 'PUT', path_parts = [_, <<"_revs_limit">>], user_ctx = Ctx} = Req, - Db -) -> - Limit = chttpd:json_body(Req), - ok = fabric:set_revs_limit(Db, Limit, [{user_ctx, Ctx}]), - send_json(Req, {[{<<"ok">>, true}]}); -db_req(#httpd{method = 'GET', path_parts = [_, <<"_revs_limit">>]} = Req, Db) -> - send_json(Req, fabric:get_revs_limit(Db)); -db_req(#httpd{path_parts = [_, <<"_revs_limit">>]} = Req, _Db) -> - send_method_not_allowed(Req, "PUT,GET"); -db_req(#httpd{method = 'PUT', path_parts = [_, <<"_purged_infos_limit">>]} = Req, Db) -> - Options = [{user_ctx, Req#httpd.user_ctx}], - case chttpd:json_body(Req) of - Limit when is_integer(Limit), Limit > 0 -> - case fabric:set_purge_infos_limit(Db, Limit, Options) of - ok -> - send_json(Req, {[{<<"ok">>, true}]}); - Error -> - throw(Error) - end; - _ -> - throw({bad_request, "`purge_infos_limit` must be positive integer"}) - end; -db_req(#httpd{method = 'GET', path_parts = [_, <<"_purged_infos_limit">>]} = Req, Db) -> - send_json(Req, fabric:get_purge_infos_limit(Db)); -% Special case to enable using an unencoded slash in the URL of design docs, -% as slashes in document IDs must otherwise be URL encoded. -db_req( - #httpd{ - method = 'GET', mochi_req = MochiReq, path_parts = [_DbName, <<"_design/", _/binary>> | _] - } = Req, - _Db -) -> - [Head | Tail] = re:split(MochiReq:get(raw_path), "_design%2F", [{return, list}, caseless]), - chttpd:send_redirect(Req, Head ++ "_design/" ++ Tail); -db_req(#httpd{path_parts = [_DbName, <<"_design">>, Name]} = Req, Db) -> - db_doc_req(Req, Db, <<"_design/", Name/binary>>); -db_req(#httpd{path_parts = [_DbName, <<"_design">>, Name | FileNameParts]} = Req, Db) -> - db_attachment_req(Req, Db, <<"_design/", Name/binary>>, FileNameParts); -% Special case to allow for accessing local documents without %2F -% encoding the docid. Throws out requests that don't have the second -% path part or that specify an attachment name. -db_req(#httpd{path_parts = [_DbName, <<"_local">>]}, _Db) -> - throw({bad_request, <<"Invalid _local document id.">>}); -db_req(#httpd{path_parts = [_DbName, <<"_local/">>]}, _Db) -> - throw({bad_request, <<"Invalid _local document id.">>}); -db_req(#httpd{path_parts = [_DbName, <<"_local">>, Name]} = Req, Db) -> - db_doc_req(Req, Db, <<"_local/", Name/binary>>); -db_req(#httpd{path_parts = [_DbName, <<"_local">> | _Rest]}, _Db) -> - throw({bad_request, <<"_local documents do not accept attachments.">>}); -db_req(#httpd{path_parts = [_, DocId]} = Req, Db) -> - db_doc_req(Req, Db, DocId); -db_req(#httpd{method = 'DELETE', path_parts = [_, DocId | FileNameParts]} = Req, Db) -> - chttpd:body(Req), - db_attachment_req(Req, Db, DocId, FileNameParts); -db_req(#httpd{path_parts = [_, DocId | FileNameParts]} = Req, Db) -> - db_attachment_req(Req, Db, DocId, FileNameParts). - -multi_all_docs_view(Req, Db, OP, Queries) -> - Args0 = couch_mrview_http:parse_params(Req, undefined), - Args1 = Args0#mrargs{view_type = map}, - ArgQueries = lists:map( - fun({Query}) -> - QueryArg1 = couch_mrview_http:parse_params( - Query, - undefined, - Args1, - [decoded] - ), - QueryArgs2 = fabric_util:validate_all_docs_args(Db, QueryArg1), - set_namespace(OP, QueryArgs2) - end, - Queries - ), - Options = [{user_ctx, Req#httpd.user_ctx}], - VAcc0 = #vacc{db = Db, req = Req, prepend = "\r\n"}, - FirstChunk = "{\"results\":[", - {ok, Resp0} = chttpd:start_delayed_json_response( - VAcc0#vacc.req, - 200, - [], - FirstChunk - ), - VAcc1 = VAcc0#vacc{resp = Resp0}, - VAcc2 = lists:foldl( - fun(Args, Acc0) -> - {ok, Acc1} = fabric:all_docs( - Db, - Options, - fun view_cb/2, - Acc0, - Args - ), - Acc1 - end, - VAcc1, - ArgQueries - ), - {ok, Resp1} = chttpd:send_delayed_chunk(VAcc2#vacc.resp, "\r\n]}"), - chttpd:end_delayed_json_response(Resp1). - -all_docs_view(Req, Db, Keys, OP) -> - Args0 = couch_mrview_http:parse_body_and_query(Req, Keys), - Args1 = Args0#mrargs{view_type = map}, - Args2 = fabric_util:validate_all_docs_args(Db, Args1), - Args3 = set_namespace(OP, Args2), - Options = [{user_ctx, Req#httpd.user_ctx}], - Max = chttpd:chunked_response_buffer_size(), - VAcc = #vacc{db = Db, req = Req, threshold = Max}, - {ok, Resp} = fabric:all_docs(Db, Options, fun view_cb/2, VAcc, Args3), - {ok, Resp#vacc.resp}. - -view_cb({row, Row} = Msg, Acc) -> - case lists:keymember(doc, 1, Row) of - true -> chttpd_stats:incr_reads(); - false -> ok - end, - chttpd_stats:incr_rows(), - couch_mrview_http:view_cb(Msg, Acc); -view_cb(Msg, Acc) -> - couch_mrview_http:view_cb(Msg, Acc). - -db_doc_req(#httpd{method = 'DELETE'} = Req, Db, DocId) -> - % check for the existence of the doc to handle the 404 case. - couch_doc_open(Db, DocId, nil, []), - case chttpd:qs_value(Req, "rev") of - undefined -> - Body = {[{<<"_deleted">>, true}]}; - Rev -> - Body = {[{<<"_rev">>, ?l2b(Rev)}, {<<"_deleted">>, true}]} - end, - Doc = couch_doc_from_req(Req, Db, DocId, Body), - send_updated_doc(Req, Db, DocId, Doc); -db_doc_req(#httpd{method = 'GET', mochi_req = MochiReq} = Req, Db, DocId) -> - #doc_query_args{ - rev = Rev0, - open_revs = Revs, - options = Options0, - atts_since = AttsSince - } = parse_doc_query(Req), - Options = [{user_ctx, Req#httpd.user_ctx} | Options0], - case Revs of - [] -> - Options2 = - if - AttsSince /= nil -> - [{atts_since, AttsSince}, attachments | Options]; - true -> - Options - end, - Rev = - case lists:member(latest, Options) of - % couch_doc_open will open the winning rev despite of a rev passed - % https://docs.couchdb.org/en/stable/api/document/common.html?highlight=latest#get--db-docid - true -> nil; - false -> Rev0 - end, - Doc = couch_doc_open(Db, DocId, Rev, Options2), - send_doc(Req, Doc, Options2); - _ -> - case fabric:open_revs(Db, DocId, Revs, Options) of - {ok, []} when Revs == all -> - chttpd:send_error(Req, {not_found, missing}); - {ok, Results} -> - chttpd_stats:incr_reads(length(Results)), - case MochiReq:accepts_content_type("multipart/mixed") of - false -> - {ok, Resp} = start_json_response(Req, 200), - send_chunk(Resp, "["), - % We loop through the docs. The first time through the separator - % is whitespace, then a comma on subsequent iterations. - lists:foldl( - fun(Result, AccSeparator) -> - case Result of - {ok, Doc} -> - JsonDoc = couch_doc:to_json_obj(Doc, Options), - Json = ?JSON_ENCODE({[{ok, JsonDoc}]}), - send_chunk(Resp, AccSeparator ++ Json); - {{not_found, missing}, RevId} -> - RevStr = couch_doc:rev_to_str(RevId), - Json = ?JSON_ENCODE({[{<<"missing">>, RevStr}]}), - send_chunk(Resp, AccSeparator ++ Json) - end, - % AccSeparator now has a comma - "," - end, - "", - Results - ), - send_chunk(Resp, "]"), - end_json_response(Resp); - true -> - send_docs_multipart(Req, Results, Options) - end; - {error, Error} -> - chttpd:send_error(Req, Error) - end - end; -db_doc_req(#httpd{method = 'POST', user_ctx = Ctx} = Req, Db, DocId) -> - couch_httpd:validate_referer(Req), - couch_db:validate_docid(Db, DocId), - chttpd:validate_ctype(Req, "multipart/form-data"), - - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - Options = [{user_ctx, Ctx}, {w, W}], - - Form = couch_httpd:parse_form(Req), - case proplists:is_defined("_doc", Form) of - true -> - Json = ?JSON_DECODE(couch_util:get_value("_doc", Form)), - Doc = couch_doc_from_req(Req, Db, DocId, Json); - false -> - Rev = couch_doc:parse_rev(list_to_binary(couch_util:get_value("_rev", Form))), - Doc = - case fabric:open_revs(Db, DocId, [Rev], []) of - {ok, [{ok, Doc0}]} -> - chttpd_stats:incr_reads(), - Doc0; - {error, Error} -> - throw(Error) - end - end, - UpdatedAtts = [ - couch_att:new([ - {name, validate_attachment_name(Name)}, - {type, list_to_binary(ContentType)}, - {data, Content} - ]) - || {Name, {ContentType, _}, Content} <- - proplists:get_all_values("_attachments", Form) - ], - #doc{atts = OldAtts} = Doc, - OldAtts2 = lists:flatmap( - fun(Att) -> - OldName = couch_att:fetch(name, Att), - case [1 || A <- UpdatedAtts, couch_att:fetch(name, A) == OldName] of - % the attachment wasn't in the UpdatedAtts, return it - [] -> [Att]; - % the attachment was in the UpdatedAtts, drop it - _ -> [] - end - end, - OldAtts - ), - NewDoc = Doc#doc{ - atts = UpdatedAtts ++ OldAtts2 - }, - case fabric:update_doc(Db, NewDoc, Options) of - {ok, NewRev} -> - chttpd_stats:incr_writes(), - HttpCode = 201; - {accepted, NewRev} -> - chttpd_stats:incr_writes(), - HttpCode = 202 - end, - send_json( - Req, - HttpCode, - [{"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewRev)) ++ "\""}], - {[ - {ok, true}, - {id, DocId}, - {rev, couch_doc:rev_to_str(NewRev)} - ]} - ); -db_doc_req(#httpd{method = 'PUT', user_ctx = Ctx} = Req, Db, DocId) -> - #doc_query_args{ - update_type = UpdateType - } = parse_doc_query(Req), - DbName = couch_db:name(Db), - couch_db:validate_docid(Db, DocId), - - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - Options = [{user_ctx, Ctx}, {w, W}], - - Loc = absolute_uri(Req, [ - $/, - couch_util:url_encode(DbName), - $/, - couch_util:url_encode(DocId) - ]), - RespHeaders = [{"Location", Loc}], - case couch_util:to_list(couch_httpd:header_value(Req, "Content-Type")) of - ("multipart/related;" ++ _) = ContentType -> - couch_httpd:check_max_request_length(Req), - couch_httpd_multipart:num_mp_writers(mem3:n(mem3:dbname(DbName), DocId)), - {ok, Doc0, WaitFun, Parser} = couch_doc:doc_from_multi_part_stream( - ContentType, - fun() -> receive_request_data(Req) end - ), - Doc = couch_doc_from_req(Req, Db, DocId, Doc0), - try - {HttpCode, RespHeaders1, RespBody} = update_doc_req( - Req, - Db, - DocId, - Doc, - RespHeaders, - UpdateType - ), - WaitFun(), - send_json(Req, HttpCode, RespHeaders1, RespBody) - catch - throw:Err -> - % Document rejected by a validate_doc_update function. - couch_httpd_multipart:abort_multipart_stream(Parser), - throw(Err) - end; - _Else -> - case chttpd:qs_value(Req, "batch") of - "ok" -> - % batch - Doc = couch_doc_from_req(Req, Db, DocId, chttpd:json_body(Req)), - - spawn(fun() -> - case catch (fabric:update_doc(Db, Doc, Options)) of - {ok, _} -> - chttpd_stats:incr_writes(), - ok; - {accepted, _} -> - chttpd_stats:incr_writes(), - ok; - Error -> - couch_log:notice("Batch doc error (~s): ~p", [DocId, Error]) - end - end), - send_json( - Req, - 202, - [], - {[ - {ok, true}, - {id, DocId} - ]} - ); - _Normal -> - % normal - Body = chttpd:json_body(Req), - Doc = couch_doc_from_req(Req, Db, DocId, Body), - send_updated_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType) - end - end; -db_doc_req(#httpd{method = 'COPY', user_ctx = Ctx} = Req, Db, SourceDocId) -> - SourceRev = - case extract_header_rev(Req, chttpd:qs_value(Req, "rev")) of - missing_rev -> nil; - Rev -> Rev - end, - {TargetDocId0, TargetRevs} = couch_httpd_db:parse_copy_destination_header(Req), - TargetDocId = list_to_binary(chttpd:unquote(TargetDocId0)), - % open old doc - Doc = couch_doc_open(Db, SourceDocId, SourceRev, []), - % save new doc - case - fabric:update_doc( - Db, - Doc#doc{id = TargetDocId, revs = TargetRevs}, - [{user_ctx, Ctx}] - ) - of - {ok, NewTargetRev} -> - chttpd_stats:incr_writes(), - HttpCode = 201; - {accepted, NewTargetRev} -> - chttpd_stats:incr_writes(), - HttpCode = 202 - end, - % respond - DbName = couch_db:name(Db), - {PartRes} = update_doc_result_to_json(TargetDocId, {ok, NewTargetRev}), - Loc = absolute_uri( - Req, "/" ++ couch_util:url_encode(DbName) ++ "/" ++ couch_util:url_encode(TargetDocId) - ), - send_json( - Req, - HttpCode, - [ - {"Location", Loc}, - {"ETag", "\"" ++ ?b2l(couch_doc:rev_to_str(NewTargetRev)) ++ "\""} - ], - {PartRes} - ); -db_doc_req(Req, _Db, _DocId) -> - send_method_not_allowed(Req, "DELETE,GET,HEAD,POST,PUT,COPY"). - -send_doc(Req, Doc, Options) -> - case Doc#doc.meta of - [] -> - DiskEtag = couch_httpd:doc_etag(Doc), - % output etag only when we have no meta - chttpd:etag_respond(Req, DiskEtag, fun() -> - send_doc_efficiently(Req, Doc, [{"ETag", DiskEtag}], Options) - end); - _ -> - send_doc_efficiently(Req, Doc, [], Options) - end. - -send_doc_efficiently(Req, #doc{atts = []} = Doc, Headers, Options) -> - send_json(Req, 200, Headers, couch_doc:to_json_obj(Doc, Options)); -send_doc_efficiently(#httpd{mochi_req = MochiReq} = Req, #doc{atts = Atts} = Doc, Headers, Options) -> - case lists:member(attachments, Options) of - true -> - Refs = monitor_attachments(Atts), - try - case MochiReq:accepts_content_type("multipart/related") of - false -> - send_json(Req, 200, Headers, couch_doc:to_json_obj(Doc, Options)); - true -> - Boundary = couch_uuids:random(), - JsonBytes = ?JSON_ENCODE( - couch_doc:to_json_obj( - Doc, - [attachments, follows, att_encoding_info | Options] - ) - ), - {ContentType, Len} = couch_doc:len_doc_to_multi_part_stream( - Boundary, JsonBytes, Atts, true - ), - CType = {"Content-Type", ContentType}, - {ok, Resp} = start_response_length(Req, 200, [CType | Headers], Len), - couch_doc:doc_to_multi_part_stream( - Boundary, - JsonBytes, - Atts, - fun(Data) -> couch_httpd:send(Resp, Data) end, - true - ) - end - after - demonitor_refs(Refs) - end; - false -> - send_json(Req, 200, Headers, couch_doc:to_json_obj(Doc, Options)) - end. - -send_docs_multipart_bulk_get(Results, Options0, OuterBoundary, Resp) -> - InnerBoundary = bulk_get_multipart_boundary(), - Options = [attachments, follows, att_encoding_info | Options0], - lists:foreach( - fun - ({ok, #doc{id = Id, revs = Revs, atts = Atts} = Doc}) -> - Refs = monitor_attachments(Doc#doc.atts), - try - JsonBytes = ?JSON_ENCODE(couch_doc:to_json_obj(Doc, Options)), - couch_httpd:send_chunk(Resp, <<"\r\n--", OuterBoundary/binary>>), - case Atts of - [] -> - couch_httpd:send_chunk( - Resp, <<"\r\nContent-Type: application/json\r\n\r\n">> - ); - _ -> - lists:foreach( - fun(Header) -> couch_httpd:send_chunk(Resp, Header) end, - bulk_get_multipart_headers(Revs, Id, InnerBoundary) - ) - end, - couch_doc:doc_to_multi_part_stream( - InnerBoundary, - JsonBytes, - Atts, - fun(Data) -> couch_httpd:send_chunk(Resp, Data) end, - true - ) - after - demonitor_refs(Refs) - end; - ({{not_found, missing}, RevId}) -> - RevStr = couch_doc:rev_to_str(RevId), - Json = ?JSON_ENCODE( - {[ - {<<"rev">>, RevStr}, - {<<"error">>, <<"not_found">>}, - {<<"reason">>, <<"missing">>} - ]} - ), - couch_httpd:send_chunk( - Resp, - [ - <<"\r\n--", OuterBoundary/binary>>, - <<"\r\nContent-Type: application/json; error=\"true\"\r\n\r\n">>, - Json - ] - ) - end, - Results - ). - -send_docs_multipart(Req, Results, Options1) -> - OuterBoundary = couch_uuids:random(), - InnerBoundary = couch_uuids:random(), - Options = [attachments, follows, att_encoding_info | Options1], - CType = {"Content-Type", "multipart/mixed; boundary=\"" ++ ?b2l(OuterBoundary) ++ "\""}, - {ok, Resp} = start_chunked_response(Req, 200, [CType]), - couch_httpd:send_chunk(Resp, <<"--", OuterBoundary/binary>>), - lists:foreach( - fun - ({ok, #doc{atts = Atts} = Doc}) -> - Refs = monitor_attachments(Doc#doc.atts), - try - JsonBytes = ?JSON_ENCODE(couch_doc:to_json_obj(Doc, Options)), - {ContentType, _Len} = couch_doc:len_doc_to_multi_part_stream( - InnerBoundary, JsonBytes, Atts, true - ), - couch_httpd:send_chunk( - Resp, <<"\r\nContent-Type: ", ContentType/binary, "\r\n\r\n">> - ), - couch_doc:doc_to_multi_part_stream( - InnerBoundary, - JsonBytes, - Atts, - fun(Data) -> couch_httpd:send_chunk(Resp, Data) end, - true - ), - couch_httpd:send_chunk(Resp, <<"\r\n--", OuterBoundary/binary>>) - after - demonitor_refs(Refs) - end; - ({{not_found, missing}, RevId}) -> - RevStr = couch_doc:rev_to_str(RevId), - Json = ?JSON_ENCODE({[{<<"missing">>, RevStr}]}), - couch_httpd:send_chunk( - Resp, - [ - <<"\r\nContent-Type: application/json; error=\"true\"\r\n\r\n">>, - Json, - <<"\r\n--", OuterBoundary/binary>> - ] - ) - end, - Results - ), - couch_httpd:send_chunk(Resp, <<"--">>), - couch_httpd:last_chunk(Resp). - -bulk_get_multipart_headers({0, []}, Id, Boundary) -> - [ - <<"\r\nX-Doc-Id: ", Id/binary>>, - <<"\r\nContent-Type: multipart/related; boundary=", Boundary/binary, "\r\n\r\n">> - ]; -bulk_get_multipart_headers({Start, [FirstRevId | _]}, Id, Boundary) -> - RevStr = couch_doc:rev_to_str({Start, FirstRevId}), - [ - <<"\r\nX-Doc-Id: ", Id/binary>>, - <<"\r\nX-Rev-Id: ", RevStr/binary>>, - <<"\r\nContent-Type: multipart/related; boundary=", Boundary/binary, "\r\n\r\n">> - ]. - -bulk_get_multipart_boundary() -> - Unique = couch_uuids:random(), - <<"--", Unique/binary>>. - -receive_request_data(Req) -> - receive_request_data(Req, chttpd:body_length(Req)). - -receive_request_data(Req, Len) when Len == chunked -> - Ref = make_ref(), - ChunkFun = fun({_Length, Binary}, _State) -> - self() ! {chunk, Ref, Binary} - end, - couch_httpd:recv_chunked(Req, 4096, ChunkFun, ok), - GetChunk = fun GC() -> - receive - {chunk, Ref, Binary} -> {Binary, GC} - end - end, - { - receive - {chunk, Ref, Binary} -> Binary - end, - GetChunk - }; -receive_request_data(Req, LenLeft) when LenLeft > 0 -> - Len = erlang:min(4096, LenLeft), - Data = chttpd:recv(Req, Len), - {Data, fun() -> receive_request_data(Req, LenLeft - iolist_size(Data)) end}; -receive_request_data(_Req, _) -> - throw(<<"expected more data">>). - -update_doc_result_to_json({error, _} = Error) -> - {_Code, Err, Msg} = chttpd:error_info(Error), - {[ - {error, Err}, - {reason, Msg} - ]}; -update_doc_result_to_json({{Id, Rev}, Error}) -> - {_Code, Err, Msg} = chttpd:error_info(Error), - {[ - {id, Id}, - {rev, couch_doc:rev_to_str(Rev)}, - {error, Err}, - {reason, Msg} - ]}. - -update_doc_result_to_json(#doc{id = DocId}, Result) -> - update_doc_result_to_json(DocId, Result); -update_doc_result_to_json(DocId, {ok, NewRev}) -> - {[{ok, true}, {id, DocId}, {rev, couch_doc:rev_to_str(NewRev)}]}; -update_doc_result_to_json(DocId, {accepted, NewRev}) -> - {[{ok, true}, {id, DocId}, {rev, couch_doc:rev_to_str(NewRev)}, {accepted, true}]}; -update_doc_result_to_json(DocId, Error) -> - {_Code, ErrorStr, Reason} = chttpd:error_info(Error), - {[{id, DocId}, {error, ErrorStr}, {reason, Reason}]}. - -purge_results_to_json([], []) -> - {201, []}; -purge_results_to_json([{DocId, _Revs} | RIn], [{ok, PRevs} | ROut]) -> - {Code, Results} = purge_results_to_json(RIn, ROut), - couch_stats:increment_counter([couchdb, document_purges, success]), - {Code, [{DocId, couch_doc:revs_to_strs(PRevs)} | Results]}; -purge_results_to_json([{DocId, _Revs} | RIn], [{accepted, PRevs} | ROut]) -> - {Code, Results} = purge_results_to_json(RIn, ROut), - couch_stats:increment_counter([couchdb, document_purges, success]), - NewResults = [{DocId, couch_doc:revs_to_strs(PRevs)} | Results], - {erlang:max(Code, 202), NewResults}; -purge_results_to_json([{DocId, _Revs} | RIn], [Error | ROut]) -> - {Code, Results} = purge_results_to_json(RIn, ROut), - {NewCode, ErrorStr, Reason} = chttpd:error_info(Error), - couch_stats:increment_counter([couchdb, document_purges, failure]), - NewResults = [{DocId, {[{error, ErrorStr}, {reason, Reason}]}} | Results], - {erlang:max(NewCode, Code), NewResults}. - -send_updated_doc(Req, Db, DocId, Json) -> - send_updated_doc(Req, Db, DocId, Json, []). - -send_updated_doc(Req, Db, DocId, Doc, Headers) -> - send_updated_doc(Req, Db, DocId, Doc, Headers, interactive_edit). - -send_updated_doc(Req, Db, DocId, Doc, Headers, Type) -> - {Code, Headers1, Body} = update_doc_req(Req, Db, DocId, Doc, Headers, Type), - send_json(Req, Code, Headers1, Body). - -update_doc_req(Req, Db, DocId, Doc, Headers, UpdateType) -> - #httpd{user_ctx = Ctx} = Req, - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - Options = - case couch_httpd:header_value(Req, "X-Couch-Full-Commit") of - "true" -> - [full_commit, UpdateType, {user_ctx, Ctx}, {w, W}]; - "false" -> - [delay_commit, UpdateType, {user_ctx, Ctx}, {w, W}]; - _ -> - [UpdateType, {user_ctx, Ctx}, {w, W}] - end, - {Status, {etag, Etag}, Body} = update_doc(Db, DocId, Doc, Options), - HttpCode = http_code_from_status(Status), - ResponseHeaders = [{"ETag", Etag} | Headers], - {HttpCode, ResponseHeaders, Body}. - -http_code_from_status(Status) -> - case Status of - accepted -> - 202; - created -> - 201; - ok -> - 200 - end. - -update_doc(Db, DocId, #doc{deleted = Deleted, body = DocBody} = Doc, Options) -> - {_, Ref} = spawn_monitor(fun() -> - try fabric:update_doc(Db, Doc, Options) of - Resp -> - exit({exit_ok, Resp}) - catch - throw:Reason -> - exit({exit_throw, Reason}); - error:Reason -> - exit({exit_error, Reason}); - exit:Reason -> - exit({exit_exit, Reason}) - end - end), - Result = - receive - {'DOWN', Ref, _, _, {exit_ok, Ret}} -> - Ret; - {'DOWN', Ref, _, _, {exit_throw, Reason}} -> - throw(Reason); - {'DOWN', Ref, _, _, {exit_error, Reason}} -> - erlang:error(Reason); - {'DOWN', Ref, _, _, {exit_exit, Reason}} -> - erlang:exit(Reason) - end, - - case Result of - {ok, NewRev} -> - Accepted = false; - {accepted, NewRev} -> - Accepted = true - end, - Etag = couch_httpd:doc_etag(DocId, DocBody, NewRev), - Status = - case {Accepted, Deleted} of - {true, _} -> - accepted; - {false, true} -> - ok; - {false, false} -> - created - end, - NewRevStr = couch_doc:rev_to_str(NewRev), - Body = {[{ok, true}, {id, DocId}, {rev, NewRevStr}]}, - {Status, {etag, Etag}, Body}. - -couch_doc_from_req(Req, _Db, DocId, #doc{revs = Revs} = Doc) -> - validate_attachment_names(Doc), - Rev = - case chttpd:qs_value(Req, "rev") of - undefined -> - undefined; - QSRev -> - couch_doc:parse_rev(QSRev) - end, - Revs2 = - case Revs of - {Start, [RevId | _]} -> - if - Rev /= undefined andalso Rev /= {Start, RevId} -> - throw( - {bad_request, - "Document rev from request body and query " - "string have different values"} - ); - true -> - case extract_header_rev(Req, {Start, RevId}) of - missing_rev -> {0, []}; - _ -> Revs - end - end; - _ -> - case extract_header_rev(Req, Rev) of - missing_rev -> {0, []}; - {Pos, RevId2} -> {Pos, [RevId2]} - end - end, - Doc#doc{id = DocId, revs = Revs2}; -couch_doc_from_req(Req, Db, DocId, Json) -> - Doc = couch_db:doc_from_json_obj_validate(Db, Json), - couch_doc_from_req(Req, Db, DocId, Doc). - -% Useful for debugging -% couch_doc_open(Db, DocId) -> -% couch_doc_open(Db, DocId, nil, []). - -couch_doc_open(Db, DocId, Rev, Options0) -> - Options = [{user_ctx, couch_db:get_user_ctx(Db)} | Options0], - case Rev of - % open most recent rev - nil -> - case fabric:open_doc(Db, DocId, Options) of - {ok, Doc} -> - chttpd_stats:incr_reads(), - Doc; - Error -> - throw(Error) - end; - % open a specific rev (deletions come back as stubs) - _ -> - case fabric:open_revs(Db, DocId, [Rev], Options) of - {ok, [{ok, Doc}]} -> - chttpd_stats:incr_reads(), - Doc; - {ok, [{{not_found, missing}, Rev}]} -> - throw(not_found); - {ok, [Else]} -> - throw(Else); - {error, Error} -> - throw(Error) - end - end. - -get_existing_attachment(Atts, FileName) -> - % Check if attachment exists, if not throw not_found - case [A || A <- Atts, couch_att:fetch(name, A) == FileName] of - [] -> throw({not_found, "Document is missing attachment"}); - [Att] -> Att - end. - -% Attachment request handlers - -db_attachment_req(#httpd{method = 'GET', mochi_req = MochiReq} = Req, Db, DocId, FileNameParts) -> - FileName = list_to_binary( - mochiweb_util:join( - lists:map( - fun binary_to_list/1, - FileNameParts - ), - "/" - ) - ), - #doc_query_args{ - rev = Rev, - options = Options - } = parse_doc_query(Req), - #doc{ - atts = Atts - } = Doc = couch_doc_open(Db, DocId, Rev, Options), - Att = get_existing_attachment(Atts, FileName), - [Type, Enc, DiskLen, AttLen, Md5] = couch_att:fetch( - [type, encoding, disk_len, att_len, md5], Att - ), - Refs = monitor_attachments(Att), - try - Etag = - case Md5 of - <<>> -> chttpd:doc_etag(Doc); - _ -> "\"" ++ ?b2l(base64:encode(Md5)) ++ "\"" - end, - ReqAcceptsAttEnc = lists:member( - atom_to_list(Enc), - couch_httpd:accepted_encodings(Req) - ), - Headers0 = - [ - {"ETag", Etag}, - {"Cache-Control", "must-revalidate"}, - {"Content-Type", binary_to_list(Type)} - ] ++ - case ReqAcceptsAttEnc of - true when Enc =/= identity -> - % RFC 2616 says that the 'identify' encoding should not be used in - % the Content-Encoding header - [{"Content-Encoding", atom_to_list(Enc)}]; - _ -> - [] - end ++ - case Enc of - identity -> - [{"Accept-Ranges", "bytes"}]; - _ -> - [{"Accept-Ranges", "none"}] - end, - Headers = chttpd_util:maybe_add_csp_header("attachments", Headers0, "sandbox"), - Len = - case {Enc, ReqAcceptsAttEnc} of - {identity, _} -> - % stored and served in identity form - DiskLen; - {_, false} when DiskLen =/= AttLen -> - % Stored encoded, but client doesn't accept the encoding we used, - % so we need to decode on the fly. DiskLen is the identity length - % of the attachment. - DiskLen; - {_, true} -> - % Stored and served encoded. AttLen is the encoded length. - AttLen; - _ -> - % We received an encoded attachment and stored it as such, so we - % don't know the identity length. The client doesn't accept the - % encoding, and since we cannot serve a correct Content-Length - % header we'll fall back to a chunked response. - undefined - end, - AttFun = - case ReqAcceptsAttEnc of - false -> - fun couch_att:foldl_decode/3; - true -> - fun couch_att:foldl/3 - end, - chttpd:etag_respond( - Req, - Etag, - fun() -> - case Len of - undefined -> - {ok, Resp} = start_chunked_response(Req, 200, Headers), - AttFun(Att, fun(Seg, _) -> send_chunk(Resp, Seg) end, {ok, Resp}), - couch_httpd:last_chunk(Resp); - _ -> - Ranges = parse_ranges(MochiReq:get(range), Len), - case {Enc, Ranges} of - {identity, [{From, To}]} -> - Headers1 = - [{"Content-Range", make_content_range(From, To, Len)}] ++ - Headers, - {ok, Resp} = start_response_length( - Req, 206, Headers1, To - From + 1 - ), - couch_att:range_foldl( - Att, - From, - To + 1, - fun(Seg, _) -> send(Resp, Seg) end, - {ok, Resp} - ); - {identity, Ranges} when is_list(Ranges) andalso length(Ranges) < 10 -> - send_ranges_multipart(Req, Type, Len, Att, Ranges); - _ -> - Headers1 = - Headers ++ - if - Enc =:= identity orelse ReqAcceptsAttEnc =:= true -> - [ - {"Content-MD5", - base64:encode(couch_att:fetch(md5, Att))} - ]; - true -> - [] - end, - {ok, Resp} = start_response_length(Req, 200, Headers1, Len), - AttFun(Att, fun(Seg, _) -> send(Resp, Seg) end, {ok, Resp}) - end - end - end - ) - after - demonitor_refs(Refs) - end; -db_attachment_req(#httpd{method = Method, user_ctx = Ctx} = Req, Db, DocId, FileNameParts) when - (Method == 'PUT') or (Method == 'DELETE') --> - FileName = validate_attachment_name( - mochiweb_util:join( - lists:map( - fun binary_to_list/1, - FileNameParts - ), - "/" - ) - ), - - NewAtt = - case Method of - 'DELETE' -> - []; - _ -> - MimeType = - case couch_httpd:header_value(Req, "Content-Type") of - % We could throw an error here or guess by the FileName. - % Currently, just giving it a default. - undefined -> <<"application/octet-stream">>; - CType -> list_to_binary(CType) - end, - Data = fabric:att_receiver(Req, couch_db:name(Db), chttpd:body_length(Req)), - ContentLen = - case couch_httpd:header_value(Req, "Content-Length") of - undefined -> undefined; - Length -> list_to_integer(Length) - end, - ContentEnc = string:to_lower( - string:strip( - couch_httpd:header_value(Req, "Content-Encoding", "identity") - ) - ), - Encoding = - case ContentEnc of - "identity" -> - identity; - "gzip" -> - gzip; - _ -> - throw({ - bad_ctype, - "Only gzip and identity content-encodings are supported" - }) - end, - [ - couch_att:new([ - {name, FileName}, - {type, MimeType}, - {data, Data}, - {att_len, ContentLen}, - {md5, get_md5_header(Req)}, - {encoding, Encoding} - ]) - ] - end, - - Doc = - case extract_header_rev(Req, chttpd:qs_value(Req, "rev")) of - % make the new doc - missing_rev -> - if - Method =/= 'DELETE' -> - ok; - true -> - % check for the existence of the doc and attachment - CurrDoc = #doc{} = couch_doc_open(Db, DocId, nil, []), - get_existing_attachment(CurrDoc#doc.atts, FileName) - end, - couch_db:validate_docid(Db, DocId), - #doc{id = DocId}; - Rev -> - case fabric:open_revs(Db, DocId, [Rev], [{user_ctx, Ctx}]) of - {ok, [{ok, Doc0}]} -> - chttpd_stats:incr_reads(), - if - Method =/= 'DELETE' -> - ok; - true -> - % check if attachment exists - get_existing_attachment(Doc0#doc.atts, FileName) - end, - Doc0; - {ok, [Error]} -> - throw(Error); - {error, Error} -> - throw(Error) - end - end, - - #doc{atts = Atts} = Doc, - DocEdited = Doc#doc{ - atts = NewAtt ++ [A || A <- Atts, couch_att:fetch(name, A) /= FileName] - }, - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - case fabric:update_doc(Db, DocEdited, [{user_ctx, Ctx}, {w, W}]) of - {ok, UpdatedRev} -> - chttpd_stats:incr_writes(), - HttpCode = 201; - {accepted, UpdatedRev} -> - chttpd_stats:incr_writes(), - HttpCode = 202 - end, - erlang:put(mochiweb_request_recv, true), - DbName = couch_db:name(Db), - - {Status, Headers} = - case Method of - 'DELETE' -> - {200, []}; - _ -> - {HttpCode, [ - {"Location", - absolute_uri(Req, [ - $/, - DbName, - $/, - couch_util:url_encode(DocId), - $/, - couch_util:url_encode(FileName) - ])} - ]} - end, - send_json( - Req, - Status, - Headers, - {[ - {ok, true}, - {id, DocId}, - {rev, couch_doc:rev_to_str(UpdatedRev)} - ]} - ); -db_attachment_req(Req, _Db, _DocId, _FileNameParts) -> - send_method_not_allowed(Req, "DELETE,GET,HEAD,PUT"). - -send_ranges_multipart(Req, ContentType, Len, Att, Ranges) -> - Boundary = couch_uuids:random(), - CType = {"Content-Type", "multipart/byteranges; boundary=\"" ++ ?b2l(Boundary) ++ "\""}, - {ok, Resp} = start_chunked_response(Req, 206, [CType]), - couch_httpd:send_chunk(Resp, <<"--", Boundary/binary>>), - lists:foreach( - fun({From, To}) -> - ContentRange = make_content_range(From, To, Len), - couch_httpd:send_chunk( - Resp, - <<"\r\nContent-Type: ", ContentType/binary, "\r\n", "Content-Range: ", - ContentRange/binary, "\r\n", "\r\n">> - ), - couch_att:range_foldl( - Att, - From, - To + 1, - fun(Seg, _) -> send_chunk(Resp, Seg) end, - {ok, Resp} - ), - couch_httpd:send_chunk(Resp, <<"\r\n--", Boundary/binary>>) - end, - Ranges - ), - couch_httpd:send_chunk(Resp, <<"--">>), - couch_httpd:last_chunk(Resp), - {ok, Resp}. - -parse_ranges(undefined, _Len) -> - undefined; -parse_ranges(fail, _Len) -> - undefined; -parse_ranges(Ranges, Len) -> - parse_ranges(Ranges, Len, []). - -parse_ranges([], _Len, Acc) -> - lists:reverse(Acc); -parse_ranges([{0, none} | _], _Len, _Acc) -> - undefined; -parse_ranges([{From, To} | _], _Len, _Acc) when - is_integer(From) andalso is_integer(To) andalso To < From --> - throw(requested_range_not_satisfiable); -parse_ranges([{From, To} | Rest], Len, Acc) when - is_integer(To) andalso To >= Len --> - parse_ranges([{From, Len - 1}] ++ Rest, Len, Acc); -parse_ranges([{none, To} | Rest], Len, Acc) -> - parse_ranges([{Len - To, Len - 1}] ++ Rest, Len, Acc); -parse_ranges([{From, none} | Rest], Len, Acc) -> - parse_ranges([{From, Len - 1}] ++ Rest, Len, Acc); -parse_ranges([{From, To} | Rest], Len, Acc) -> - parse_ranges(Rest, Len, [{From, To}] ++ Acc). - -make_content_range(From, To, Len) -> - ?l2b(io_lib:format("bytes ~B-~B/~B", [From, To, Len])). - -get_md5_header(Req) -> - ContentMD5 = couch_httpd:header_value(Req, "Content-MD5"), - Length = couch_httpd:body_length(Req), - Trailer = couch_httpd:header_value(Req, "Trailer"), - case {ContentMD5, Length, Trailer} of - _ when is_list(ContentMD5) orelse is_binary(ContentMD5) -> - base64:decode(ContentMD5); - {_, chunked, undefined} -> - <<>>; - {_, chunked, _} -> - case re:run(Trailer, "\\bContent-MD5\\b", [caseless]) of - {match, _} -> - md5_in_footer; - _ -> - <<>> - end; - _ -> - <<>> - end. - -parse_doc_query(Req) -> - lists:foldl(fun parse_doc_query/2, #doc_query_args{}, chttpd:qs(Req)). - -parse_shards_opt(Req) -> - [ - {n, parse_shards_opt("n", Req, config:get_integer("cluster", "n", 3))}, - {q, parse_shards_opt("q", Req, config:get_integer("cluster", "q", 2))}, - {placement, - parse_shards_opt( - "placement", Req, config:get("cluster", "placement") - )} - ]. - -parse_shards_opt("placement", Req, Default) -> - Err = <<"The `placement` value should be in a format `zone:n`.">>, - case chttpd:qs_value(Req, "placement", Default) of - Default -> - Default; - [] -> - throw({bad_request, Err}); - Val -> - try - true = lists:all( - fun(Rule) -> - [_, N] = string:tokens(Rule, ":"), - couch_util:validate_positive_int(N) - end, - string:tokens(Val, ",") - ), - Val - catch - _:_ -> - throw({bad_request, Err}) - end - end; -parse_shards_opt(Param, Req, Default) -> - Val = chttpd:qs_value(Req, Param, Default), - Err = ?l2b(["The `", Param, "` value should be a positive integer."]), - case couch_util:validate_positive_int(Val) of - true -> Val; - false -> throw({bad_request, Err}) - end. - -parse_engine_opt(Req) -> - case chttpd:qs_value(Req, "engine") of - undefined -> - []; - Extension -> - Available = couch_server:get_engine_extensions(), - case lists:member(Extension, Available) of - true -> - [{engine, iolist_to_binary(Extension)}]; - false -> - throw({bad_request, invalid_engine_extension}) - end - end. - -parse_partitioned_opt(Req) -> - case chttpd:qs_value(Req, "partitioned") of - undefined -> - []; - "false" -> - []; - "true" -> - ok = validate_partitioned_db_enabled(Req), - [ - {partitioned, true}, - {hash, [couch_partition, hash, []]} - ]; - _ -> - throw({bad_request, <<"Invalid `partitioned` parameter">>}) - end. - -validate_partitioned_db_enabled(Req) -> - case couch_flags:is_enabled(partitioned, Req) of - true -> - ok; - false -> - throw({bad_request, <<"Partitioned feature is not enabled.">>}) - end. - -parse_doc_query({Key, Value}, Args) -> - case {Key, Value} of - {"attachments", "true"} -> - Options = [attachments | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"meta", "true"} -> - Options = [revs_info, conflicts, deleted_conflicts | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"revs", "true"} -> - Options = [revs | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"local_seq", "true"} -> - Options = [local_seq | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"revs_info", "true"} -> - Options = [revs_info | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"conflicts", "true"} -> - Options = [conflicts | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"deleted", "true"} -> - Options = [deleted | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"deleted_conflicts", "true"} -> - Options = [deleted_conflicts | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"rev", Rev} -> - Args#doc_query_args{rev = couch_doc:parse_rev(Rev)}; - {"open_revs", "all"} -> - Args#doc_query_args{open_revs = all}; - {"open_revs", RevsJsonStr} -> - JsonArray = ?JSON_DECODE(RevsJsonStr), - Args#doc_query_args{open_revs = couch_doc:parse_revs(JsonArray)}; - {"latest", "true"} -> - Options = [latest | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"atts_since", RevsJsonStr} -> - JsonArray = ?JSON_DECODE(RevsJsonStr), - Args#doc_query_args{atts_since = couch_doc:parse_revs(JsonArray)}; - {"new_edits", "false"} -> - Args#doc_query_args{update_type = replicated_changes}; - {"new_edits", "true"} -> - Args#doc_query_args{update_type = interactive_edit}; - {"att_encoding_info", "true"} -> - Options = [att_encoding_info | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"r", R} -> - Options = [{r, R} | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - {"w", W} -> - Options = [{w, W} | Args#doc_query_args.options], - Args#doc_query_args{options = Options}; - % unknown key value pair, ignore. - _Else -> - Args - end. - -parse_changes_query(Req) -> - erlang:erase(changes_seq_interval), - ChangesArgs = lists:foldl( - fun({Key, Value}, Args) -> - case {string:to_lower(Key), Value} of - {"feed", "live"} -> - %% sugar for continuous - Args#changes_args{feed = "continuous"}; - {"feed", _} -> - Args#changes_args{feed = Value}; - {"descending", "true"} -> - Args#changes_args{dir = rev}; - {"since", _} -> - Args#changes_args{since = Value}; - {"last-event-id", _} -> - Args#changes_args{since = Value}; - {"limit", _} -> - Args#changes_args{limit = list_to_integer(Value)}; - {"style", _} -> - Args#changes_args{style = list_to_existing_atom(Value)}; - {"heartbeat", "true"} -> - Args#changes_args{heartbeat = true}; - {"heartbeat", _} -> - try list_to_integer(Value) of - HeartbeatInteger when HeartbeatInteger > 0 -> - Args#changes_args{heartbeat = HeartbeatInteger}; - _ -> - throw( - {bad_request, - <<"The heartbeat value should be a positive integer (in milliseconds).">>} - ) - catch - error:badarg -> - throw( - {bad_request, - <<"Invalid heartbeat value. Expecting a positive integer value (in milliseconds).">>} - ) - end; - {"timeout", _} -> - Args#changes_args{timeout = list_to_integer(Value)}; - {"include_docs", "true"} -> - Args#changes_args{include_docs = true}; - {"conflicts", "true"} -> - Args#changes_args{conflicts = true}; - {"attachments", "true"} -> - Options = [attachments | Args#changes_args.doc_options], - Args#changes_args{doc_options = Options}; - {"att_encoding_info", "true"} -> - Options = [att_encoding_info | Args#changes_args.doc_options], - Args#changes_args{doc_options = Options}; - {"filter", _} -> - Args#changes_args{filter = Value}; - {"seq_interval", _} -> - try list_to_integer(Value) of - V when V > 0 -> - erlang:put(changes_seq_interval, V), - Args; - _ -> - throw({bad_request, invalid_seq_interval}) - catch - error:badarg -> - throw({bad_request, invalid_seq_interval}) - end; - % unknown key value pair, ignore. - _Else -> - Args - end - end, - #changes_args{}, - chttpd:qs(Req) - ), - %% if it's an EventSource request with a Last-event-ID header - %% that should override the `since` query string, since it's - %% probably the browser reconnecting. - case ChangesArgs#changes_args.feed of - "eventsource" -> - case couch_httpd:header_value(Req, "last-event-id") of - undefined -> - ChangesArgs; - Value -> - ChangesArgs#changes_args{since = Value} - end; - _ -> - ChangesArgs - end. - -extract_header_rev(Req, ExplicitRev) when is_binary(ExplicitRev) or is_list(ExplicitRev) -> - extract_header_rev(Req, couch_doc:parse_rev(ExplicitRev)); -extract_header_rev(Req, ExplicitRev) -> - Etag = - case chttpd:header_value(Req, "If-Match") of - undefined -> undefined; - Value -> couch_doc:parse_rev(string:strip(Value, both, $")) - end, - case {ExplicitRev, Etag} of - {undefined, undefined} -> missing_rev; - {_, undefined} -> ExplicitRev; - {undefined, _} -> Etag; - _ when ExplicitRev == Etag -> Etag; - _ -> throw({bad_request, "Document rev and etag have different values"}) - end. - -validate_security_can_be_edited(DbName) -> - UserDbName = config:get("chttpd_auth", "authentication_db", "_users"), - CanEditUserSecurityObject = config:get("couchdb", "users_db_security_editable", "false"), - case {DbName, CanEditUserSecurityObject} of - {UserDbName, "false"} -> - Msg = "You can't edit the security object of the user database.", - throw({forbidden, Msg}); - {_, _} -> - ok - end. - -validate_revs(_Doc, true) -> - ok; -validate_revs(#doc{revs = {0, []}}, false) -> - throw( - {bad_request, - ?l2b( - "When `new_edits: false`, " ++ - "the document needs `_rev` or `_revisions` specified" - )} - ); -validate_revs(_Doc, false) -> - ok. - -validate_attachment_names(Doc) -> - lists:foreach( - fun(Att) -> - Name = couch_att:fetch(name, Att), - validate_attachment_name(Name) - end, - Doc#doc.atts - ). - -validate_attachment_name(Name) when is_list(Name) -> - validate_attachment_name(list_to_binary(Name)); -validate_attachment_name(<<"_", Rest/binary>>) -> - throw( - {bad_request, - <<"Attachment name '_", Rest/binary, "' starts with prohibited character '_'">>} - ); -validate_attachment_name(Name) -> - case couch_util:validate_utf8(Name) of - true -> Name; - false -> throw({bad_request, <<"Attachment name is not UTF-8 encoded">>}) - end. - --spec monitor_attachments(couch_att:att() | [couch_att:att()]) -> [reference()]. -monitor_attachments(Atts) when is_list(Atts) -> - lists:foldl( - fun(Att, Monitors) -> - case couch_att:fetch(data, Att) of - {Fd, _} -> - [monitor(process, Fd) | Monitors]; - stub -> - Monitors; - Else -> - couch_log:error("~p from couch_att:fetch(data, ~p)", [Else, Att]), - Monitors - end - end, - [], - Atts - ); -monitor_attachments(Att) -> - monitor_attachments([Att]). - -demonitor_refs(Refs) when is_list(Refs) -> - [demonitor(Ref) || Ref <- Refs]. - -set_namespace(<<"_all_docs">>, Args) -> - set_namespace(undefined, Args); -set_namespace(<<"_local_docs">>, Args) -> - set_namespace(<<"_local">>, Args); -set_namespace(<<"_design_docs">>, Args) -> - set_namespace(<<"_design">>, Args); -set_namespace(NS, #mrargs{} = Args) -> - couch_mrview_util:set_extra(Args, namespace, NS). - -%% /db/_bulk_get stuff - -bulk_get_parse_doc_query(Req) -> - lists:foldl( - fun({Key, Value}, Args) -> - ok = validate_query_param(Key), - parse_doc_query({Key, Value}, Args) - end, - #doc_query_args{}, - chttpd:qs(Req) - ). - -validate_query_param("open_revs" = Key) -> - throw_bad_query_param(Key); -validate_query_param("new_edits" = Key) -> - throw_bad_query_param(Key); -validate_query_param("w" = Key) -> - throw_bad_query_param(Key); -validate_query_param("rev" = Key) -> - throw_bad_query_param(Key); -validate_query_param("atts_since" = Key) -> - throw_bad_query_param(Key); -validate_query_param(_) -> - ok. - -throw_bad_query_param(Key) when is_list(Key) -> - throw_bad_query_param(?l2b(Key)); -throw_bad_query_param(Key) when is_binary(Key) -> - Msg = <<"\"", Key/binary, "\" query parameter is not acceptable">>, - throw({bad_request, Msg}). - -bulk_get_open_doc_revs(Db, {Props}, Options) -> - bulk_get_open_doc_revs1(Db, Props, Options, {}). - -bulk_get_open_doc_revs1(Db, Props, Options, {}) -> - case couch_util:get_value(<<"id">>, Props) of - undefined -> - Error = {null, bad_request, <<"document id missed">>}, - {null, {error, Error}, Options}; - DocId -> - try - couch_db:validate_docid(Db, DocId), - bulk_get_open_doc_revs1(Db, Props, Options, {DocId}) - catch - throw:{Error, Reason} -> - {DocId, {error, {null, Error, Reason}}, Options} - end - end; -bulk_get_open_doc_revs1(Db, Props, Options, {DocId}) -> - RevStr = couch_util:get_value(<<"rev">>, Props), - - case parse_field(<<"rev">>, RevStr) of - {error, {RevStr, Error, Reason}} -> - {DocId, {error, {RevStr, Error, Reason}}, Options}; - {ok, undefined} -> - bulk_get_open_doc_revs1(Db, Props, Options, {DocId, all}); - {ok, Rev} -> - bulk_get_open_doc_revs1(Db, Props, Options, {DocId, [Rev]}) - end; -bulk_get_open_doc_revs1(Db, Props, Options, {DocId, Revs}) -> - AttsSinceStr = couch_util:get_value(<<"atts_since">>, Props), - - case parse_field(<<"atts_since">>, AttsSinceStr) of - {error, {BadAttsSinceRev, Error, Reason}} -> - {DocId, {error, {BadAttsSinceRev, Error, Reason}}, Options}; - {ok, []} -> - bulk_get_open_doc_revs1(Db, Props, Options, {DocId, Revs, Options}); - {ok, RevList} -> - Options1 = [{atts_since, RevList}, attachments | Options], - bulk_get_open_doc_revs1(Db, Props, Options, {DocId, Revs, Options1}) - end; -bulk_get_open_doc_revs1(Db, Props, _, {DocId, Revs, Options}) -> - case fabric:open_revs(Db, DocId, Revs, Options) of - {ok, []} -> - RevStr = couch_util:get_value(<<"rev">>, Props), - Error = {RevStr, <<"not_found">>, <<"missing">>}, - {DocId, {error, Error}, Options}; - {ok, Resps} = Results -> - chttpd_stats:incr_reads(length(Resps)), - {DocId, Results, Options}; - Else -> - {DocId, Else, Options} - end. - -parse_field(<<"rev">>, undefined) -> - {ok, undefined}; -parse_field(<<"rev">>, Value) -> - try - Rev = couch_doc:parse_rev(Value), - {ok, Rev} - catch - throw:{bad_request = Error, Reason} -> - {error, {Value, Error, Reason}} - end; -parse_field(<<"atts_since">>, undefined) -> - {ok, []}; -parse_field(<<"atts_since">>, []) -> - {ok, []}; -parse_field(<<"atts_since">>, Value) when is_list(Value) -> - parse_atts_since(Value, []); -parse_field(<<"atts_since">>, Value) -> - {error, {Value, bad_request, <<"att_since value must be array of revs.">>}}. - -parse_atts_since([], Acc) -> - {ok, lists:reverse(Acc)}; -parse_atts_since([RevStr | Rest], Acc) -> - case parse_field(<<"rev">>, RevStr) of - {ok, Rev} -> - parse_atts_since(Rest, [Rev | Acc]); - {error, _} = Error -> - Error - end. - -bulk_get_send_docs_json(Resp, DocId, Results, Options, Sep) -> - Id = ?JSON_ENCODE(DocId), - send_chunk(Resp, [Sep, <<"{\"id\": ">>, Id, <<", \"docs\": [">>]), - bulk_get_send_docs_json1(Resp, DocId, Results, Options), - send_chunk(Resp, <<"]}">>). - -bulk_get_send_docs_json1(Resp, DocId, {error, {Rev, Error, Reason}}, _) -> - send_chunk(Resp, [bulk_get_json_error(DocId, Rev, Error, Reason)]); -bulk_get_send_docs_json1(_Resp, _DocId, {ok, []}, _) -> - ok; -bulk_get_send_docs_json1(Resp, DocId, {ok, Docs}, Options) -> - lists:foldl( - fun(Result, AccSeparator) -> - case Result of - {ok, Doc} -> - JsonDoc = couch_doc:to_json_obj(Doc, Options), - Json = ?JSON_ENCODE({[{ok, JsonDoc}]}), - send_chunk(Resp, [AccSeparator, Json]); - {{Error, Reason}, RevId} -> - RevStr = couch_doc:rev_to_str(RevId), - Json = bulk_get_json_error(DocId, RevStr, Error, Reason), - send_chunk(Resp, [AccSeparator, Json]) - end, - <<",">> - end, - <<"">>, - Docs - ). - -bulk_get_json_error(DocId, Rev, Error, Reason) -> - ?JSON_ENCODE( - {[ - {error, - {[ - {<<"id">>, DocId}, - {<<"rev">>, Rev}, - {<<"error">>, Error}, - {<<"reason">>, Reason} - ]}} - ]} - ). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - -monitor_attachments_test_() -> - {"ignore stubs", fun() -> - Atts = [couch_att:new([{data, stub}])], - ?_assertEqual([], monitor_attachments(Atts)) - end}. - -parse_partitioned_opt_test_() -> - { - foreach, - fun setup/0, - fun teardown/1, - [ - t_should_allow_partitioned_db(), - t_should_throw_on_not_allowed_partitioned_db(), - t_returns_empty_array_for_partitioned_false(), - t_returns_empty_array_for_no_partitioned_qs() - ] - }. - -parse_shards_opt_test_() -> - { - foreach, - fun setup/0, - fun teardown/1, - [ - t_should_allow_valid_q(), - t_should_default_on_missing_q(), - t_should_throw_on_invalid_q(), - t_should_allow_valid_n(), - t_should_default_on_missing_n(), - t_should_throw_on_invalid_n(), - t_should_allow_valid_placement(), - t_should_default_on_missing_placement(), - t_should_throw_on_invalid_placement() - ] - }. - -setup() -> - meck:expect(config, get, fun(_, _, Default) -> Default end), - ok. - -teardown(_) -> - meck:unload(). - -mock_request(Url) -> - Headers = mochiweb_headers:make([{"Host", "examples.com"}]), - MochiReq = mochiweb_request:new(nil, 'PUT', Url, {1, 1}, Headers), - #httpd{mochi_req = MochiReq}. - -t_should_allow_partitioned_db() -> - ?_test(begin - meck:expect(couch_flags, is_enabled, 2, true), - Req = mock_request("/all-test21?partitioned=true"), - [Partitioned, _] = parse_partitioned_opt(Req), - ?assertEqual(Partitioned, {partitioned, true}) - end). - -t_should_throw_on_not_allowed_partitioned_db() -> - ?_test(begin - meck:expect(couch_flags, is_enabled, 2, false), - Req = mock_request("/all-test21?partitioned=true"), - Throw = {bad_request, <<"Partitioned feature is not enabled.">>}, - ?assertThrow(Throw, parse_partitioned_opt(Req)) - end). - -t_returns_empty_array_for_partitioned_false() -> - ?_test(begin - Req = mock_request("/all-test21?partitioned=false"), - ?assertEqual(parse_partitioned_opt(Req), []) - end). - -t_returns_empty_array_for_no_partitioned_qs() -> - ?_test(begin - Req = mock_request("/all-test21"), - ?assertEqual(parse_partitioned_opt(Req), []) - end). - -t_should_allow_valid_q() -> - ?_test(begin - Req = mock_request("/all-test21?q=1"), - Opts = parse_shards_opt(Req), - ?assertEqual("1", couch_util:get_value(q, Opts)) - end). - -t_should_default_on_missing_q() -> - ?_test(begin - Req = mock_request("/all-test21"), - Opts = parse_shards_opt(Req), - ?assertEqual(2, couch_util:get_value(q, Opts)) - end). - -t_should_throw_on_invalid_q() -> - ?_test(begin - Req = mock_request("/all-test21?q="), - Err = <<"The `q` value should be a positive integer.">>, - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end). - -t_should_allow_valid_n() -> - ?_test(begin - Req = mock_request("/all-test21?n=1"), - Opts = parse_shards_opt(Req), - ?assertEqual("1", couch_util:get_value(n, Opts)) - end). - -t_should_default_on_missing_n() -> - ?_test(begin - Req = mock_request("/all-test21"), - Opts = parse_shards_opt(Req), - ?assertEqual(3, couch_util:get_value(n, Opts)) - end). - -t_should_throw_on_invalid_n() -> - ?_test(begin - Req = mock_request("/all-test21?n="), - Err = <<"The `n` value should be a positive integer.">>, - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end). - -t_should_allow_valid_placement() -> - { - foreach, - fun() -> ok end, - [ - {"single zone", - ?_test(begin - Req = mock_request("/all-test21?placement=az:1"), - Opts = parse_shards_opt(Req), - ?assertEqual("az:1", couch_util:get_value(placement, Opts)) - end)}, - {"multi zone", - ?_test(begin - Req = mock_request("/all-test21?placement=az:1,co:3"), - Opts = parse_shards_opt(Req), - ?assertEqual( - "az:1,co:3", - couch_util:get_value(placement, Opts) - ) - end)} - ] - }. - -t_should_default_on_missing_placement() -> - ?_test(begin - Req = mock_request("/all-test21"), - Opts = parse_shards_opt(Req), - ?assertEqual(undefined, couch_util:get_value(placement, Opts)) - end). - -t_should_throw_on_invalid_placement() -> - Err = <<"The `placement` value should be in a format `zone:n`.">>, - { - foreach, - fun() -> ok end, - [ - {"empty placement", - ?_test(begin - Req = mock_request("/all-test21?placement="), - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end)}, - {"invalid format", - ?_test(begin - Req = mock_request("/all-test21?placement=moon"), - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end)}, - {"invalid n", - ?_test(begin - Req = mock_request("/all-test21?placement=moon:eagle"), - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end)}, - {"one invalid zone", - ?_test(begin - Req = mock_request("/all-test21?placement=az:1,co:moon"), - ?assertThrow({bad_request, Err}, parse_shards_opt(Req)) - end)} - ] - }. - --endif. diff --git a/src/chttpd/src/chttpd_epi.erl b/src/chttpd/src/chttpd_epi.erl deleted file mode 100644 index 5536c9e4d..000000000 --- a/src/chttpd/src/chttpd_epi.erl +++ /dev/null @@ -1,52 +0,0 @@ -% 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. - --module(chttpd_epi). - --behaviour(couch_epi_plugin). - --export([ - app/0, - providers/0, - services/0, - data_subscriptions/0, - data_providers/0, - processes/0, - notify/3 -]). - -app() -> - chttpd. - -providers() -> - [ - {chttpd_handlers, chttpd_httpd_handlers} - ]. - -services() -> - [ - {chttpd_auth, chttpd_auth}, - {chttpd_handlers, chttpd_handlers}, - {chttpd, chttpd_plugin} - ]. - -data_subscriptions() -> - []. - -data_providers() -> - []. - -processes() -> - []. - -notify(_Key, _Old, _New) -> - ok. diff --git a/src/chttpd/src/chttpd_external.erl b/src/chttpd/src/chttpd_external.erl deleted file mode 100644 index 352087d58..000000000 --- a/src/chttpd/src/chttpd_external.erl +++ /dev/null @@ -1,218 +0,0 @@ -% 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. - --module(chttpd_external). - --compile(tuple_calls). - --export([send_external_response/2]). --export([json_req_obj_fields/0, json_req_obj/2, json_req_obj/3, json_req_obj/4]). --export([default_or_content_type/2, parse_external_response/1]). - --import(chttpd, [send_error/4]). - --include_lib("couch/include/couch_db.hrl"). - -json_req_obj(Req, Db) -> - json_req_obj(Req, Db, null). -json_req_obj(Req, Db, DocId) -> - json_req_obj(Req, Db, DocId, all). -json_req_obj(Req, Db, DocId, all) -> - Fields = json_req_obj_fields(), - json_req_obj(Req, Db, DocId, Fields); -json_req_obj(Req, Db, DocId, Fields) when is_list(Fields) -> - {[{Field, json_req_obj_field(Field, Req, Db, DocId)} || Field <- Fields]}. - -json_req_obj_fields() -> - [ - <<"info">>, - <<"uuid">>, - <<"id">>, - <<"method">>, - <<"requested_path">>, - <<"path">>, - <<"raw_path">>, - <<"query">>, - <<"headers">>, - <<"body">>, - <<"peer">>, - <<"form">>, - <<"cookie">>, - <<"userCtx">>, - <<"secObj">> - ]. - -json_req_obj_field(<<"info">>, #httpd{}, Db, _DocId) -> - {ok, Info} = get_db_info(Db), - {Info}; -json_req_obj_field(<<"uuid">>, #httpd{}, _Db, _DocId) -> - couch_uuids:new(); -json_req_obj_field(<<"id">>, #httpd{}, _Db, DocId) -> - DocId; -json_req_obj_field(<<"method">>, #httpd{method = Method}, _Db, _DocId) -> - Method; -json_req_obj_field(<<"requested_path">>, #httpd{requested_path_parts = Path}, _Db, _DocId) -> - Path; -json_req_obj_field(<<"path">>, #httpd{path_parts = Path}, _Db, _DocId) -> - Path; -json_req_obj_field(<<"raw_path">>, #httpd{mochi_req = Req}, _Db, _DocId) -> - ?l2b(Req:get(raw_path)); -json_req_obj_field(<<"query">>, #httpd{mochi_req = Req}, _Db, _DocId) -> - json_query_keys(to_json_terms(Req:parse_qs())); -json_req_obj_field(<<"headers">>, #httpd{mochi_req = Req}, _Db, _DocId) -> - Headers = Req:get(headers), - Hlist = mochiweb_headers:to_list(Headers), - to_json_terms(Hlist); -json_req_obj_field(<<"body">>, #httpd{req_body = undefined, mochi_req = Req}, _Db, _DocId) -> - MaxSize = chttpd_util:get_chttpd_config_integer( - "max_http_request_size", 4294967296 - ), - try - Req:recv_body(MaxSize) - catch - exit:{shutdown, _} -> - exit({bad_request, <<"Invalid request body">>}); - exit:normal -> - exit({bad_request, <<"Invalid request body">>}) - end; -json_req_obj_field(<<"body">>, #httpd{req_body = Body}, _Db, _DocId) -> - Body; -json_req_obj_field(<<"peer">>, #httpd{peer = undefined, mochi_req = Req}, _, _) -> - ?l2b(Req:get(peer)); -json_req_obj_field(<<"peer">>, #httpd{peer = Peer}, _Db, _DocId) -> - ?l2b(Peer); -json_req_obj_field(<<"form">>, #httpd{mochi_req = Req, method = Method} = HttpReq, Db, DocId) -> - Body = json_req_obj_field(<<"body">>, HttpReq, Db, DocId), - ParsedForm = - case Req:get_primary_header_value("content-type") of - "application/x-www-form-urlencoded" ++ _ when - Method =:= 'POST' orelse Method =:= 'PUT' - -> - mochiweb_util:parse_qs(Body); - _ -> - [] - end, - to_json_terms(ParsedForm); -json_req_obj_field(<<"cookie">>, #httpd{mochi_req = Req}, _Db, _DocId) -> - to_json_terms(Req:parse_cookie()); -json_req_obj_field(<<"userCtx">>, #httpd{}, Db, _DocId) -> - couch_util:json_user_ctx(Db); -json_req_obj_field(<<"secObj">>, #httpd{user_ctx = UserCtx}, Db, _DocId) -> - get_db_security(Db, UserCtx). - -get_db_info(Db) -> - case couch_db:is_clustered(Db) of - true -> - fabric:get_db_info(Db); - false -> - couch_db:get_db_info(Db) - end. - -get_db_security(Db, #user_ctx{}) -> - case couch_db:is_clustered(Db) of - true -> - fabric:get_security(Db); - false -> - couch_db:get_security(Db) - end. - -to_json_terms(Data) -> - to_json_terms(Data, []). -to_json_terms([], Acc) -> - {lists:reverse(Acc)}; -to_json_terms([{Key, Value} | Rest], Acc) when is_atom(Key) -> - to_json_terms(Rest, [{list_to_binary(atom_to_list(Key)), list_to_binary(Value)} | Acc]); -to_json_terms([{Key, Value} | Rest], Acc) -> - to_json_terms(Rest, [{list_to_binary(Key), list_to_binary(Value)} | Acc]). - -json_query_keys({Json}) -> - json_query_keys(Json, []). -json_query_keys([], Acc) -> - {lists:reverse(Acc)}; -json_query_keys([{<<"startkey">>, Value} | Rest], Acc) -> - json_query_keys(Rest, [{<<"startkey">>, ?JSON_DECODE(Value)} | Acc]); -json_query_keys([{<<"endkey">>, Value} | Rest], Acc) -> - json_query_keys(Rest, [{<<"endkey">>, ?JSON_DECODE(Value)} | Acc]); -json_query_keys([{<<"key">>, Value} | Rest], Acc) -> - json_query_keys(Rest, [{<<"key">>, ?JSON_DECODE(Value)} | Acc]); -json_query_keys([{<<"descending">>, Value} | Rest], Acc) -> - json_query_keys(Rest, [{<<"descending">>, ?JSON_DECODE(Value)} | Acc]); -json_query_keys([Term | Rest], Acc) -> - json_query_keys(Rest, [Term | Acc]). - -send_external_response(Req, Response) -> - #extern_resp_args{ - code = Code, - data = Data, - ctype = CType, - headers = Headers0, - json = Json - } = parse_external_response(Response), - Headers1 = default_or_content_type(CType, Headers0), - case Json of - nil -> - Headers2 = chttpd_util:maybe_add_csp_header("showlist", Headers1, "sandbox"), - chttpd:send_response(Req, Code, Headers2, Data); - Json -> - chttpd:send_json(Req, Code, Headers1, Json) - end. - -parse_external_response({Response}) -> - lists:foldl( - fun({Key, Value}, Args) -> - case {Key, Value} of - {"", _} -> - Args; - {<<"code">>, Value} -> - Args#extern_resp_args{code = Value}; - {<<"stop">>, true} -> - Args#extern_resp_args{stop = true}; - {<<"json">>, Value} -> - Args#extern_resp_args{ - json = Value, - ctype = "application/json" - }; - {<<"body">>, Value} -> - Args#extern_resp_args{data = Value, ctype = "text/html; charset=utf-8"}; - {<<"base64">>, Value} -> - Args#extern_resp_args{ - data = base64:decode(Value), - ctype = "application/binary" - }; - {<<"headers">>, {Headers}} -> - NewHeaders = lists:map( - fun({Header, HVal}) -> - {couch_util:to_list(Header), couch_util:to_list(HVal)} - end, - Headers - ), - Args#extern_resp_args{headers = NewHeaders}; - % unknown key - _ -> - Msg = lists:flatten( - io_lib:format("Invalid data from external server: ~p", [{Key, Value}]) - ), - throw({external_response_error, Msg}) - end - end, - #extern_resp_args{}, - Response - ). - -default_or_content_type(DefaultContentType, Headers) -> - IsContentType = fun({X, _}) -> string:to_lower(X) == "content-type" end, - case lists:any(IsContentType, Headers) of - false -> - [{"Content-Type", DefaultContentType} | Headers]; - true -> - Headers - end. diff --git a/src/chttpd/src/chttpd_handlers.erl b/src/chttpd/src/chttpd_handlers.erl deleted file mode 100644 index 82eee7365..000000000 --- a/src/chttpd/src/chttpd_handlers.erl +++ /dev/null @@ -1,88 +0,0 @@ -% 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. - --module(chttpd_handlers). - --export([ - url_handler/2, - db_handler/2, - design_handler/2 -]). - --define(SERVICE_ID, chttpd_handlers). - --include_lib("couch/include/couch_db.hrl"). - -%% ------------------------------------------------------------------ -%% API Function Definitions -%% ------------------------------------------------------------------ - -url_handler(HandlerKey, DefaultFun) -> - select(collect(url_handler, [HandlerKey]), DefaultFun). - -db_handler(HandlerKey, DefaultFun) -> - select(collect(db_handler, [HandlerKey]), DefaultFun). - -design_handler(HandlerKey, DefaultFun) -> - select(collect(design_handler, [HandlerKey]), DefaultFun). - -%% ------------------------------------------------------------------ -%% Internal Function Definitions -%% ------------------------------------------------------------------ - -collect(Func, Args) -> - Results = do_apply(Func, Args, []), - [HandlerFun || HandlerFun <- Results, HandlerFun /= no_match]. - -do_apply(Func, Args, Opts) -> - Handle = couch_epi:get_handle(?SERVICE_ID), - couch_epi:apply(Handle, ?SERVICE_ID, Func, Args, Opts). - -select([], Default) -> - Default; -select([{default, OverrideDefault}], _Default) -> - OverrideDefault; -select(Handlers, _Default) -> - [Handler] = do_select(Handlers, []), - Handler. - -do_select([], Acc) -> - Acc; -do_select([{override, Handler} | _], _Acc) -> - [Handler]; -do_select([{default, _} | Rest], Acc) -> - do_select(Rest, Acc); -do_select([Handler], Acc) -> - [Handler | Acc]; -do_select([Handler | Rest], Acc) -> - do_select(Rest, [Handler | Acc]). - --ifdef(TEST). --include_lib("eunit/include/eunit.hrl"). - -select_override_test() -> - ?assertEqual(selected, select([{override, selected}, foo], default)), - ?assertEqual(selected, select([foo, {override, selected}], default)), - ?assertEqual(selected, select([{override, selected}, {override, bar}], default)), - ?assertError({badmatch, [bar, foo]}, select([foo, bar], default)). - -select_default_override_test() -> - ?assertEqual(selected, select([{default, new_default}, selected], old_default)), - ?assertEqual(selected, select([selected, {default, new_default}], old_default)), - ?assertEqual(selected, select([{default, selected}], old_default)), - ?assertEqual(selected, select([], selected)), - ?assertEqual( - selected, - select([{default, new_default}, {override, selected}, bar], old_default) - ). - --endif. diff --git a/src/chttpd/src/chttpd_httpd_handlers.erl b/src/chttpd/src/chttpd_httpd_handlers.erl deleted file mode 100644 index 932b52e5f..000000000 --- a/src/chttpd/src/chttpd_httpd_handlers.erl +++ /dev/null @@ -1,46 +0,0 @@ -% 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. - --module(chttpd_httpd_handlers). - --export([url_handler/1, db_handler/1, design_handler/1]). - -url_handler(<<>>) -> fun chttpd_misc:handle_welcome_req/1; -url_handler(<<"favicon.ico">>) -> fun chttpd_misc:handle_favicon_req/1; -url_handler(<<"_utils">>) -> fun chttpd_misc:handle_utils_dir_req/1; -url_handler(<<"_all_dbs">>) -> fun chttpd_misc:handle_all_dbs_req/1; -url_handler(<<"_dbs_info">>) -> fun chttpd_misc:handle_dbs_info_req/1; -url_handler(<<"_active_tasks">>) -> fun chttpd_misc:handle_task_status_req/1; -url_handler(<<"_scheduler">>) -> fun couch_replicator_httpd:handle_scheduler_req/1; -url_handler(<<"_node">>) -> fun chttpd_node:handle_node_req/1; -url_handler(<<"_reload_query_servers">>) -> fun chttpd_misc:handle_reload_query_servers_req/1; -url_handler(<<"_replicate">>) -> fun chttpd_misc:handle_replicate_req/1; -url_handler(<<"_uuids">>) -> fun chttpd_misc:handle_uuids_req/1; -url_handler(<<"_session">>) -> fun chttpd_auth:handle_session_req/1; -url_handler(<<"_up">>) -> fun chttpd_misc:handle_up_req/1; -url_handler(_) -> no_match. - -db_handler(<<"_view_cleanup">>) -> fun chttpd_db:handle_view_cleanup_req/2; -db_handler(<<"_compact">>) -> fun chttpd_db:handle_compact_req/2; -db_handler(<<"_design">>) -> fun chttpd_db:handle_design_req/2; -db_handler(<<"_partition">>) -> fun chttpd_db:handle_partition_req/2; -db_handler(<<"_temp_view">>) -> fun chttpd_view:handle_temp_view_req/2; -db_handler(<<"_changes">>) -> fun chttpd_db:handle_changes_req/2; -db_handler(_) -> no_match. - -design_handler(<<"_view">>) -> fun chttpd_view:handle_view_req/3; -design_handler(<<"_show">>) -> fun chttpd_show:handle_doc_show_req/3; -design_handler(<<"_list">>) -> fun chttpd_show:handle_view_list_req/3; -design_handler(<<"_update">>) -> fun chttpd_show:handle_doc_update_req/3; -design_handler(<<"_info">>) -> fun chttpd_db:handle_design_info_req/3; -design_handler(<<"_rewrite">>) -> fun chttpd_rewrite:handle_rewrite_req/3; -design_handler(_) -> no_match. diff --git a/src/chttpd/src/chttpd_misc.erl b/src/chttpd/src/chttpd_misc.erl deleted file mode 100644 index 0dedeba4d..000000000 --- a/src/chttpd/src/chttpd_misc.erl +++ /dev/null @@ -1,328 +0,0 @@ -% 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. - --module(chttpd_misc). - --export([ - handle_all_dbs_req/1, - handle_dbs_info_req/1, - handle_favicon_req/1, - handle_favicon_req/2, - handle_replicate_req/1, - handle_reload_query_servers_req/1, - handle_task_status_req/1, - handle_up_req/1, - handle_utils_dir_req/1, - handle_utils_dir_req/2, - handle_uuids_req/1, - handle_welcome_req/1, - handle_welcome_req/2 -]). - --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). - --import( - chttpd, - [ - send_json/2, send_json/3, - send_method_not_allowed/2, - send_chunk/2, - start_chunked_response/3 - ] -). - --define(MAX_DB_NUM_FOR_DBS_INFO, 100). - -% httpd global handlers - -handle_welcome_req(Req) -> - handle_welcome_req(Req, <<"Welcome">>). - -handle_welcome_req(#httpd{method = 'GET'} = Req, WelcomeMessage) -> - send_json(Req, { - [ - {couchdb, WelcomeMessage}, - {version, list_to_binary(couch_server:get_version())}, - {git_sha, list_to_binary(couch_server:get_git_sha())}, - {uuid, couch_server:get_uuid()}, - {features, get_features()} - ] ++ - case config:get("vendor") of - [] -> - []; - Properties -> - [{vendor, {[{?l2b(K), ?l2b(V)} || {K, V} <- Properties]}}] - end - }); -handle_welcome_req(Req, _) -> - send_method_not_allowed(Req, "GET,HEAD"). - -get_features() -> - case dreyfus:available() of - true -> - [search | config:features()]; - false -> - config:features() - end. - -handle_favicon_req(Req) -> - handle_favicon_req(Req, get_docroot()). - -handle_favicon_req(#httpd{method = 'GET'} = Req, DocumentRoot) -> - {DateNow, TimeNow} = calendar:universal_time(), - DaysNow = calendar:date_to_gregorian_days(DateNow), - DaysWhenExpires = DaysNow + 365, - DateWhenExpires = calendar:gregorian_days_to_date(DaysWhenExpires), - CachingHeaders = [ - %favicon should expire a year from now - {"Cache-Control", "public, max-age=31536000"}, - {"Expires", couch_util:rfc1123_date({DateWhenExpires, TimeNow})} - ], - chttpd:serve_file(Req, "favicon.ico", DocumentRoot, CachingHeaders); -handle_favicon_req(Req, _) -> - send_method_not_allowed(Req, "GET,HEAD"). - -handle_utils_dir_req(Req) -> - handle_utils_dir_req(Req, get_docroot()). - -handle_utils_dir_req(#httpd{method = 'GET'} = Req, DocumentRoot) -> - "/" ++ UrlPath = chttpd:path(Req), - case chttpd:partition(UrlPath) of - {_ActionKey, "/", RelativePath} -> - % GET /_utils/path or GET /_utils/ - CachingHeaders = [{"Cache-Control", "private, must-revalidate"}], - DefaultValues = - "child-src 'self' data: blob:; default-src 'self'; img-src 'self' data:; font-src 'self'; " - "script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';", - Headers = chttpd_util:maybe_add_csp_header("utils", CachingHeaders, DefaultValues), - chttpd:serve_file(Req, RelativePath, DocumentRoot, Headers); - {_ActionKey, "", _RelativePath} -> - % GET /_utils - RedirectPath = chttpd:path(Req) ++ "/", - chttpd:send_redirect(Req, RedirectPath) - end; -handle_utils_dir_req(Req, _) -> - send_method_not_allowed(Req, "GET,HEAD"). - -handle_all_dbs_req(#httpd{method = 'GET'} = Req) -> - handle_all_dbs_info_req(Req); -handle_all_dbs_req(Req) -> - send_method_not_allowed(Req, "GET,HEAD"). - -handle_all_dbs_info_req(Req) -> - Args0 = couch_mrview_http:parse_params(Req, undefined), - Args1 = couch_mrview_util:set_extra(Args0, namespace, <<"_non_design">>), - ShardDbName = config:get("mem3", "shards_db", "_dbs"), - %% shard_db is not sharded but mem3:shards treats it as an edge case - %% so it can be pushed thru fabric - {ok, Info} = fabric:get_db_info(ShardDbName), - Etag = couch_httpd:make_etag({Info}), - Options = [{user_ctx, Req#httpd.user_ctx}], - {ok, Resp} = chttpd:etag_respond(Req, Etag, fun() -> - {ok, Resp} = chttpd:start_delayed_json_response(Req, 200, [{"ETag", Etag}]), - VAcc = #vacc{req = Req, resp = Resp}, - fabric:all_docs(ShardDbName, Options, fun all_dbs_info_callback/2, VAcc, Args1) - end), - case is_record(Resp, vacc) of - true -> {ok, Resp#vacc.resp}; - _ -> {ok, Resp} - end. - -all_dbs_info_callback({meta, _Meta}, #vacc{resp = Resp0} = Acc) -> - {ok, Resp1} = chttpd:send_delayed_chunk(Resp0, "["), - {ok, Acc#vacc{resp = Resp1}}; -all_dbs_info_callback({row, Row}, #vacc{resp = Resp0} = Acc) when - Acc#vacc.req#httpd.path_parts =:= [<<"_all_dbs">>] --> - Prepend = couch_mrview_http:prepend_val(Acc), - DbName = couch_util:get_value(id, Row), - {ok, Resp1} = chttpd:send_delayed_chunk(Resp0, [Prepend, ?JSON_ENCODE(DbName)]), - {ok, Acc#vacc{prepend = ",", resp = Resp1}}; -all_dbs_info_callback({row, Row}, #vacc{resp = Resp0} = Acc) when - Acc#vacc.req#httpd.path_parts =:= [<<"_dbs_info">>] --> - Prepend = couch_mrview_http:prepend_val(Acc), - DbName = couch_util:get_value(id, Row), - case chttpd_util:get_db_info(DbName) of - {ok, DbInfo} -> - Chunk = [Prepend, ?JSON_ENCODE({[{key, DbName}, {info, {DbInfo}}]})], - {ok, Resp1} = chttpd:send_delayed_chunk(Resp0, Chunk), - {ok, Acc#vacc{prepend = ",", resp = Resp1}}; - {error, database_does_not_exist} -> - {ok, Acc#vacc{resp = Resp0}}; - {error, Reason} -> - {ok, Resp1} = chttpd:send_delayed_error(Resp0, Reason), - {stop, Acc#vacc{resp = Resp1}} - end; -all_dbs_info_callback(complete, #vacc{resp = Resp0} = Acc) -> - {ok, Resp1} = chttpd:send_delayed_chunk(Resp0, "]"), - {ok, Resp2} = chttpd:end_delayed_json_response(Resp1), - {ok, Acc#vacc{resp = Resp2}}; -all_dbs_info_callback({error, Reason}, #vacc{resp = Resp0} = Acc) -> - {ok, Resp1} = chttpd:send_delayed_error(Resp0, Reason), - {ok, Acc#vacc{resp = Resp1}}. - -handle_dbs_info_req(#httpd{method = 'GET'} = Req) -> - handle_all_dbs_info_req(Req); -handle_dbs_info_req(#httpd{method = 'POST'} = Req) -> - chttpd:validate_ctype(Req, "application/json"), - Props = chttpd:json_body_obj(Req), - Keys = couch_mrview_util:get_view_keys(Props), - case Keys of - undefined -> throw({bad_request, "`keys` member must exist."}); - _ -> ok - end, - MaxNumber = config:get_integer( - "chttpd", - "max_db_number_for_dbs_info_req", - ?MAX_DB_NUM_FOR_DBS_INFO - ), - case length(Keys) =< MaxNumber of - true -> ok; - false -> throw({bad_request, too_many_keys}) - end, - {ok, Resp} = chttpd:start_json_response(Req, 200), - send_chunk(Resp, "["), - lists:foldl( - fun(DbName, AccSeparator) -> - case catch fabric:get_db_info(DbName) of - {ok, Result} -> - Json = ?JSON_ENCODE({[{key, DbName}, {info, {Result}}]}), - send_chunk(Resp, AccSeparator ++ Json); - _ -> - Json = ?JSON_ENCODE({[{key, DbName}, {error, not_found}]}), - send_chunk(Resp, AccSeparator ++ Json) - end, - % AccSeparator now has a comma - "," - end, - "", - Keys - ), - send_chunk(Resp, "]"), - chttpd:end_json_response(Resp); -handle_dbs_info_req(Req) -> - send_method_not_allowed(Req, "GET,HEAD,POST"). - -handle_task_status_req(#httpd{method = 'GET'} = Req) -> - ok = chttpd:verify_is_server_admin(Req), - {Replies, _BadNodes} = gen_server:multi_call(couch_task_status, all), - Response = lists:flatmap( - fun({Node, Tasks}) -> - [{[{node, Node} | Task]} || Task <- Tasks] - end, - Replies - ), - send_json(Req, lists:sort(Response)); -handle_task_status_req(Req) -> - send_method_not_allowed(Req, "GET,HEAD"). - -handle_replicate_req(#httpd{method = 'POST', user_ctx = Ctx, req_body = PostBody} = Req) -> - chttpd:validate_ctype(Req, "application/json"), - %% see HACK in chttpd.erl about replication - case replicate(PostBody, Ctx) of - {ok, {continuous, RepId}} -> - send_json(Req, 202, {[{ok, true}, {<<"_local_id">>, RepId}]}); - {ok, {cancelled, RepId}} -> - send_json(Req, 200, {[{ok, true}, {<<"_local_id">>, RepId}]}); - {ok, {JsonResults}} -> - send_json(Req, {[{ok, true} | JsonResults]}); - {ok, stopped} -> - send_json(Req, 200, {[{ok, stopped}]}); - {error, not_found = Error} -> - chttpd:send_error(Req, Error); - {error, {_, _} = Error} -> - chttpd:send_error(Req, Error); - {_, _} = Error -> - chttpd:send_error(Req, Error) - end; -handle_replicate_req(Req) -> - send_method_not_allowed(Req, "POST"). - -replicate({Props} = PostBody, Ctx) -> - case couch_util:get_value(<<"cancel">>, Props) of - true -> - cancel_replication(PostBody, Ctx); - _ -> - Node = choose_node([ - couch_util:get_value(<<"source">>, Props), - couch_util:get_value(<<"target">>, Props) - ]), - case rpc:call(Node, couch_replicator, replicate, [PostBody, Ctx]) of - {badrpc, Reason} -> - erlang:error(Reason); - Res -> - Res - end - end. - -cancel_replication(PostBody, Ctx) -> - {Res, _Bad} = rpc:multicall(couch_replicator, replicate, [PostBody, Ctx]), - case [X || {ok, {cancelled, _}} = X <- Res] of - [Success | _] -> - % Report success if at least one node canceled the replication - Success; - [] -> - case lists:usort(Res) of - [UniqueReply] -> - % Report a universally agreed-upon reply - UniqueReply; - [] -> - {error, badrpc}; - Else -> - % Unclear what to do here -- pick the first error? - % Except try ignoring any {error, not_found} responses - % because we'll always get two of those - hd(Else -- [{error, not_found}]) - end - end. - -choose_node(Key) when is_binary(Key) -> - Checksum = erlang:crc32(Key), - Nodes = lists:sort([node() | erlang:nodes()]), - lists:nth(1 + Checksum rem length(Nodes), Nodes); -choose_node(Key) -> - choose_node(term_to_binary(Key)). - -handle_reload_query_servers_req(#httpd{method = 'POST'} = Req) -> - chttpd:validate_ctype(Req, "application/json"), - ok = couch_proc_manager:reload(), - send_json(Req, 200, {[{ok, true}]}); -handle_reload_query_servers_req(Req) -> - send_method_not_allowed(Req, "POST"). - -handle_uuids_req(Req) -> - couch_httpd_misc_handlers:handle_uuids_req(Req). - -handle_up_req(#httpd{method = 'GET'} = Req) -> - case config:get("couchdb", "maintenance_mode") of - "true" -> - send_json(Req, 404, {[{status, maintenance_mode}]}); - "nolb" -> - send_json(Req, 404, {[{status, nolb}]}); - _ -> - {ok, {Status}} = mem3_seeds:get_status(), - case couch_util:get_value(status, Status) of - ok -> - send_json(Req, 200, {Status}); - seeding -> - send_json(Req, 404, {Status}) - end - end; -handle_up_req(Req) -> - send_method_not_allowed(Req, "GET,HEAD"). - -get_docroot() -> - % if the env var isn’t set, let’s not throw an error, but - % assume the current working dir is what we want - os:getenv("COUCHDB_FAUXTON_DOCROOT", ""). diff --git a/src/chttpd/src/chttpd_node.erl b/src/chttpd/src/chttpd_node.erl deleted file mode 100644 index cc3370a73..000000000 --- a/src/chttpd/src/chttpd_node.erl +++ /dev/null @@ -1,385 +0,0 @@ -% 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. - --module(chttpd_node). --compile(tuple_calls). - --export([ - handle_node_req/1, - get_stats/0, - run_queues/0 -]). - --include_lib("couch/include/couch_db.hrl"). - --import( - chttpd, - [ - send_json/2, send_json/3, - send_method_not_allowed/2, - send_chunk/2, - start_chunked_response/3 - ] -). - -% Node-specific request handler (_config and _stats) -% Support _local meaning this node -handle_node_req(#httpd{path_parts = [_, <<"_local">>]} = Req) -> - send_json(Req, 200, {[{name, node()}]}); -handle_node_req(#httpd{path_parts = [A, <<"_local">> | Rest]} = Req) -> - handle_node_req(Req#httpd{path_parts = [A, node()] ++ Rest}); -% GET /_node/$node/_versions -handle_node_req(#httpd{method = 'GET', path_parts = [_, _Node, <<"_versions">>]} = Req) -> - IcuVer = couch_ejson_compare:get_icu_version(), - UcaVer = couch_ejson_compare:get_uca_version(), - ColVer = couch_ejson_compare:get_collator_version(), - send_json(Req, 200, #{ - erlang_version => ?l2b(?COUCHDB_ERLANG_VERSION), - collation_driver => #{ - name => <<"libicu">>, - library_version => couch_util:version_to_binary(IcuVer), - collation_algorithm_version => couch_util:version_to_binary(UcaVer), - collator_version => couch_util:version_to_binary(ColVer) - }, - javascript_engine => #{ - name => <<"spidermonkey">>, - version => couch_server:get_spidermonkey_version() - } - }); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_versions">>]} = Req) -> - send_method_not_allowed(Req, "GET"); -% GET /_node/$node/_config -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_config">>]} = Req) -> - Grouped = lists:foldl( - fun({{Section, Key}, Value}, Acc) -> - case dict:is_key(Section, Acc) of - true -> - dict:append(Section, {list_to_binary(Key), list_to_binary(Value)}, Acc); - false -> - dict:store(Section, [{list_to_binary(Key), list_to_binary(Value)}], Acc) - end - end, - dict:new(), - call_node(Node, config, all, []) - ), - KVs = dict:fold( - fun(Section, Values, Acc) -> - [{list_to_binary(Section), {Values}} | Acc] - end, - [], - Grouped - ), - send_json(Req, 200, {KVs}); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_config">>]} = Req) -> - send_method_not_allowed(Req, "GET"); -% POST /_node/$node/_config/_reload - Flushes unpersisted config values from RAM -handle_node_req( - #httpd{method = 'POST', path_parts = [_, Node, <<"_config">>, <<"_reload">>]} = Req -) -> - case call_node(Node, config, reload, []) of - ok -> - send_json(Req, 200, {[{ok, true}]}); - {error, Reason} -> - chttpd:send_error(Req, {bad_request, Reason}) - end; -handle_node_req(#httpd{path_parts = [_, _Node, <<"_config">>, <<"_reload">>]} = Req) -> - send_method_not_allowed(Req, "POST"); -% GET /_node/$node/_config/Section -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_config">>, Section]} = Req) -> - KVs = [ - {list_to_binary(Key), list_to_binary(Value)} - || {Key, Value} <- call_node(Node, config, get, [Section]) - ], - send_json(Req, 200, {KVs}); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_config">>, _Section]} = Req) -> - send_method_not_allowed(Req, "GET"); -% PUT /_node/$node/_config/Section/Key -% "value" -handle_node_req(#httpd{method = 'PUT', path_parts = [_, Node, <<"_config">>, Section, Key]} = Req) -> - couch_util:check_config_blacklist(Section), - Value = couch_util:trim(chttpd:json_body(Req)), - Persist = chttpd:header_value(Req, "X-Couch-Persist") /= "false", - OldValue = call_node(Node, config, get, [Section, Key, ""]), - IsSensitive = Section == <<"admins">>, - Opts = #{persist => Persist, sensitive => IsSensitive}, - case call_node(Node, config, set, [Section, Key, ?b2l(Value), Opts]) of - ok -> - send_json(Req, 200, list_to_binary(OldValue)); - {error, Reason} -> - chttpd:send_error(Req, {bad_request, Reason}) - end; -% GET /_node/$node/_config/Section/Key -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_config">>, Section, Key]} = Req) -> - case call_node(Node, config, get, [Section, Key, undefined]) of - undefined -> - throw({not_found, unknown_config_value}); - Value -> - send_json(Req, 200, list_to_binary(Value)) - end; -% DELETE /_node/$node/_config/Section/Key -handle_node_req( - #httpd{method = 'DELETE', path_parts = [_, Node, <<"_config">>, Section, Key]} = Req -) -> - couch_util:check_config_blacklist(Section), - Persist = chttpd:header_value(Req, "X-Couch-Persist") /= "false", - case call_node(Node, config, get, [Section, Key, undefined]) of - undefined -> - throw({not_found, unknown_config_value}); - OldValue -> - case call_node(Node, config, delete, [Section, Key, Persist]) of - ok -> - send_json(Req, 200, list_to_binary(OldValue)); - {error, Reason} -> - chttpd:send_error(Req, {bad_request, Reason}) - end - end; -handle_node_req(#httpd{path_parts = [_, _Node, <<"_config">>, _Section, _Key]} = Req) -> - send_method_not_allowed(Req, "GET,PUT,DELETE"); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_config">>, _Section, _Key | _]} = Req) -> - chttpd:send_error(Req, not_found); -% GET /_node/$node/_stats -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_stats">> | Path]} = Req) -> - flush(Node, Req), - Stats0 = call_node(Node, couch_stats, fetch, []), - Stats = couch_stats_httpd:transform_stats(Stats0), - Nested = couch_stats_httpd:nest(Stats), - EJSON0 = couch_stats_httpd:to_ejson(Nested), - EJSON1 = couch_stats_httpd:extract_path(Path, EJSON0), - chttpd:send_json(Req, EJSON1); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_stats">>]} = Req) -> - send_method_not_allowed(Req, "GET"); -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_prometheus">>]} = Req) -> - Metrics = call_node(Node, couch_prometheus_server, scrape, []), - Version = call_node(Node, couch_prometheus_server, version, []), - Type = "text/plain; version=" ++ Version, - Header = [{<<"Content-Type">>, ?l2b(Type)}], - chttpd:send_response(Req, 200, Header, Metrics); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_prometheus">>]} = Req) -> - send_method_not_allowed(Req, "GET"); -% GET /_node/$node/_system -handle_node_req(#httpd{method = 'GET', path_parts = [_, Node, <<"_system">>]} = Req) -> - Stats = call_node(Node, chttpd_node, get_stats, []), - EJSON = couch_stats_httpd:to_ejson(Stats), - send_json(Req, EJSON); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_system">>]} = Req) -> - send_method_not_allowed(Req, "GET"); -% POST /_node/$node/_restart -handle_node_req(#httpd{method = 'POST', path_parts = [_, Node, <<"_restart">>]} = Req) -> - call_node(Node, init, restart, []), - send_json(Req, 200, {[{ok, true}]}); -handle_node_req(#httpd{path_parts = [_, _Node, <<"_restart">>]} = Req) -> - send_method_not_allowed(Req, "POST"); -handle_node_req(#httpd{ - path_parts = [_, Node | PathParts], - mochi_req = MochiReq0 -}) -> - % strip /_node/{node} from Req0 before descending further - RawUri = MochiReq0:get(raw_path), - {_, Query, Fragment} = mochiweb_util:urlsplit_path(RawUri), - NewPath0 = "/" ++ lists:join("/", [couch_util:url_encode(P) || P <- PathParts]), - NewRawPath = mochiweb_util:urlunsplit_path({NewPath0, Query, Fragment}), - MaxSize = chttpd_util:get_chttpd_config_integer( - "max_http_request_size", 4294967296 - ), - NewOpts = [{body, MochiReq0:recv_body(MaxSize)} | MochiReq0:get(opts)], - Ref = erlang:make_ref(), - MochiReq = mochiweb_request:new( - {remote, self(), Ref}, - NewOpts, - MochiReq0:get(method), - NewRawPath, - MochiReq0:get(version), - MochiReq0:get(headers) - ), - call_node(Node, couch_httpd, handle_request, [MochiReq]), - recv_loop(Ref, MochiReq0); -handle_node_req(#httpd{path_parts = [_]} = Req) -> - chttpd:send_error(Req, {bad_request, <<"Incomplete path to _node request">>}); -handle_node_req(Req) -> - chttpd:send_error(Req, not_found). - -recv_loop(Ref, ReqResp) -> - receive - {Ref, Code, Headers, _Args, start_response} -> - recv_loop(Ref, ReqResp:start({Code, Headers})); - {Ref, Code, Headers, Len, start_response_length} -> - recv_loop(Ref, ReqResp:start_response_length({Code, Headers, Len})); - {Ref, Code, Headers, chunked, respond} -> - Resp = ReqResp:respond({Code, Headers, chunked}), - recv_loop(Ref, Resp); - {Ref, Code, Headers, Args, respond} -> - Resp = ReqResp:respond({Code, Headers, Args}), - {ok, Resp}; - {Ref, send, Data} -> - ReqResp:send(Data), - {ok, ReqResp}; - {Ref, chunk, <<>>} -> - ReqResp:write_chunk(<<>>), - {ok, ReqResp}; - {Ref, chunk, Data} -> - ReqResp:write_chunk(Data), - recv_loop(Ref, ReqResp); - _Else -> - recv_loop(Ref, ReqResp) - end. - -call_node(Node0, Mod, Fun, Args) when is_binary(Node0) -> - Node1 = - try - list_to_existing_atom(?b2l(Node0)) - catch - error:badarg -> - throw({not_found, <<"no such node: ", Node0/binary>>}) - end, - call_node(Node1, Mod, Fun, Args); -call_node(Node, Mod, Fun, Args) when is_atom(Node) -> - case rpc:call(Node, Mod, Fun, Args) of - {badrpc, nodedown} -> - Reason = ?l2b(io_lib:format("~s is down", [Node])), - throw({error, {nodedown, Reason}}); - Else -> - Else - end. - -flush(Node, Req) -> - case couch_util:get_value("flush", chttpd:qs(Req)) of - "true" -> - call_node(Node, couch_stats_aggregator, flush, []); - _Else -> - ok - end. - -get_stats() -> - Other = - erlang:memory(system) - - lists:sum([ - X - || {_, X} <- - erlang:memory([atom, code, binary, ets]) - ]), - Memory = [ - {other, Other} - | erlang:memory([ - atom, - atom_used, - processes, - processes_used, - binary, - code, - ets - ]) - ], - {NumberOfGCs, WordsReclaimed, _} = statistics(garbage_collection), - {{input, Input}, {output, Output}} = statistics(io), - {CF, CDU} = db_pid_stats(), - MessageQueues0 = [ - {couch_file, {CF}}, - {couch_db_updater, {CDU}}, - {couch_server, couch_server:aggregate_queue_len()}, - {index_server, couch_index_server:aggregate_queue_len()} - ], - MessageQueues = MessageQueues0 ++ message_queues(registered()), - {SQ, DCQ} = run_queues(), - [ - {uptime, couch_app:uptime() div 1000}, - {memory, {Memory}}, - {run_queue, SQ}, - {run_queue_dirty_cpu, DCQ}, - {ets_table_count, length(ets:all())}, - {context_switches, element(1, statistics(context_switches))}, - {reductions, element(1, statistics(reductions))}, - {garbage_collection_count, NumberOfGCs}, - {words_reclaimed, WordsReclaimed}, - {io_input, Input}, - {io_output, Output}, - {os_proc_count, couch_proc_manager:get_proc_count()}, - {stale_proc_count, couch_proc_manager:get_stale_proc_count()}, - {process_count, erlang:system_info(process_count)}, - {process_limit, erlang:system_info(process_limit)}, - {message_queues, {MessageQueues}}, - {internal_replication_jobs, mem3_sync:get_backlog()}, - {distribution, {get_distribution_stats()}} - ]. - -db_pid_stats() -> - {monitors, M} = process_info(whereis(couch_stats_process_tracker), monitors), - Candidates = [Pid || {process, Pid} <- M], - CouchFiles = db_pid_stats(couch_file, Candidates), - CouchDbUpdaters = db_pid_stats(couch_db_updater, Candidates), - {CouchFiles, CouchDbUpdaters}. - -db_pid_stats(Mod, Candidates) -> - Mailboxes = lists:foldl( - fun(Pid, Acc) -> - case process_info(Pid, [message_queue_len, dictionary]) of - undefined -> - Acc; - PI -> - Dictionary = proplists:get_value(dictionary, PI, []), - case proplists:get_value('$initial_call', Dictionary) of - {Mod, init, 1} -> - case proplists:get_value(message_queue_len, PI) of - undefined -> Acc; - Len -> [Len | Acc] - end; - _ -> - Acc - end - end - end, - [], - Candidates - ), - format_pid_stats(Mailboxes). - -format_pid_stats([]) -> - []; -format_pid_stats(Mailboxes) -> - Sorted = lists:sort(Mailboxes), - Count = length(Sorted), - [ - {count, Count}, - {min, hd(Sorted)}, - {max, lists:nth(Count, Sorted)}, - {'50', lists:nth(round(Count * 0.5), Sorted)}, - {'90', lists:nth(round(Count * 0.9), Sorted)}, - {'99', lists:nth(round(Count * 0.99), Sorted)} - ]. - -get_distribution_stats() -> - lists:map( - fun({Node, Socket}) -> - {ok, Stats} = inet:getstat(Socket), - {Node, {Stats}} - end, - erlang:system_info(dist_ctrl) - ). - -message_queues(Registered) -> - lists:map( - fun(Name) -> - Type = message_queue_len, - {Type, Length} = process_info(whereis(Name), Type), - {Name, Length} - end, - Registered - ). - -%% Workaround for https://bugs.erlang.org/browse/ERL-1355 -run_queues() -> - case erlang:system_info(dirty_cpu_schedulers) > 0 of - false -> - {statistics(run_queue), 0}; - true -> - [DCQ | SQs] = lists:reverse(statistics(run_queue_lengths)), - {lists:sum(SQs), DCQ} - end. diff --git a/src/chttpd/src/chttpd_plugin.erl b/src/chttpd/src/chttpd_plugin.erl deleted file mode 100644 index 03d8ad6ac..000000000 --- a/src/chttpd/src/chttpd_plugin.erl +++ /dev/null @@ -1,64 +0,0 @@ -% 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. - --module(chttpd_plugin). - --export([ - before_request/1, - after_request/2, - handle_error/1, - before_response/4, - before_serve_file/5 -]). - --define(SERVICE_ID, chttpd). - --include_lib("couch/include/couch_db.hrl"). - -%% ------------------------------------------------------------------ -%% API Function Definitions -%% ------------------------------------------------------------------ - -before_request(HttpReq) -> - [HttpReq1] = with_pipe(before_request, [HttpReq]), - {ok, HttpReq1}. - -after_request(HttpReq, Result) -> - [_, Result1] = with_pipe(after_request, [HttpReq, Result]), - {ok, Result1}. - -handle_error(Error) -> - [Error1] = with_pipe(handle_error, [Error]), - Error1. - -before_response(HttpReq0, Code0, Headers0, Value0) -> - [HttpReq, Code, Headers, Value] = - with_pipe(before_response, [HttpReq0, Code0, Headers0, Value0]), - {ok, {HttpReq, Code, Headers, Value}}. - -before_serve_file(Req0, Code0, Headers0, RelativePath0, DocumentRoot0) -> - [HttpReq, Code, Headers, RelativePath, DocumentRoot] = - with_pipe(before_serve_file, [ - Req0, Code0, Headers0, RelativePath0, DocumentRoot0 - ]), - {ok, {HttpReq, Code, Headers, RelativePath, DocumentRoot}}. - -%% ------------------------------------------------------------------ -%% Internal Function Definitions -%% ------------------------------------------------------------------ - -with_pipe(Func, Args) -> - do_apply(Func, Args, [pipe]). - -do_apply(Func, Args, Opts) -> - Handle = couch_epi:get_handle(?SERVICE_ID), - couch_epi:apply(Handle, ?SERVICE_ID, Func, Args, Opts). diff --git a/src/chttpd/src/chttpd_prefer_header.erl b/src/chttpd/src/chttpd_prefer_header.erl deleted file mode 100644 index dbce54e65..000000000 --- a/src/chttpd/src/chttpd_prefer_header.erl +++ /dev/null @@ -1,61 +0,0 @@ -% 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. - --module(chttpd_prefer_header). - --compile(tuple_calls). - --export([ - maybe_return_minimal/2 -]). - --include_lib("couch/include/couch_db.hrl"). - --define(DEFAULT_PREFER_MINIMAL, - "Cache-Control, Content-Length, Content-Range, " - "Content-Type, ETag, Server, Transfer-Encoding, Vary" -). - -maybe_return_minimal(#httpd{mochi_req = MochiReq}, Headers) -> - case get_prefer_header(MochiReq) of - "return=minimal" -> - filter_headers(Headers, get_header_list()); - _ -> - Headers - end. - -get_prefer_header(Req) -> - case Req:get_header_value("Prefer") of - Value when is_list(Value) -> - string:to_lower(Value); - undefined -> - undefined - end. - -filter_headers(Headers, IncludeList) -> - lists:filter( - fun({HeaderName, _}) -> - lists:member(HeaderName, IncludeList) - end, - Headers - ). - -get_header_list() -> - SectionStr = config:get( - "chttpd", - "prefer_minimal", - ?DEFAULT_PREFER_MINIMAL - ), - split_list(SectionStr). - -split_list(S) -> - re:split(S, "\\s*,\\s*", [trim, {return, list}]). diff --git a/src/chttpd/src/chttpd_rewrite.erl b/src/chttpd/src/chttpd_rewrite.erl deleted file mode 100644 index 4e77597d4..000000000 --- a/src/chttpd/src/chttpd_rewrite.erl +++ /dev/null @@ -1,553 +0,0 @@ -% 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. -% -% bind_path is based on bind method from Webmachine - -%% @doc Module for URL rewriting by pattern matching. - --module(chttpd_rewrite). - --compile(tuple_calls). - --export([handle_rewrite_req/3]). --include_lib("couch/include/couch_db.hrl"). - --define(SEPARATOR, $\/). --define(MATCH_ALL, {bind, <<"*">>}). - -handle_rewrite_req(#httpd{} = Req, Db, DDoc) -> - RewritesSoFar = erlang:get(?REWRITE_COUNT), - MaxRewrites = chttpd_util:get_chttpd_config_integer("rewrite_limit", 100), - case RewritesSoFar >= MaxRewrites of - true -> - throw({bad_request, <<"Exceeded rewrite recursion limit">>}); - false -> - erlang:put(?REWRITE_COUNT, RewritesSoFar + 1) - end, - case get_rules(DDoc) of - Rules when is_list(Rules) -> - do_rewrite(Req, Rules); - Rules when is_binary(Rules) -> - case couch_query_servers:rewrite(Req, Db, DDoc) of - undefined -> - chttpd:send_error( - Req, - 404, - <<"rewrite_error">>, - <<"Invalid path.">> - ); - Rewrite -> - do_rewrite(Req, Rewrite) - end; - undefined -> - chttpd:send_error( - Req, - 404, - <<"rewrite_error">>, - <<"Invalid path.">> - ) - end. - -get_rules(#doc{body = {Props}}) -> - couch_util:get_value(<<"rewrites">>, Props). - -do_rewrite(#httpd{mochi_req = MochiReq} = Req, {Props} = Rewrite) when is_list(Props) -> - case couch_util:get_value(<<"code">>, Props) of - undefined -> - Method = rewrite_method(Req, Rewrite), - Headers = rewrite_headers(Req, Rewrite), - Path = ?b2l(rewrite_path(Req, Rewrite)), - NewMochiReq = mochiweb_request:new( - MochiReq:get(socket), - Method, - Path, - MochiReq:get(version), - Headers - ), - Body = - case couch_util:get_value(<<"body">>, Props) of - undefined -> erlang:get(mochiweb_request_body); - B -> B - end, - NewMochiReq:cleanup(), - case Body of - undefined -> []; - _ -> erlang:put(mochiweb_request_body, Body) - end, - couch_log:debug("rewrite to ~p", [Path]), - chttpd:handle_request_int(NewMochiReq); - Code -> - chttpd:send_response( - Req, - Code, - case couch_util:get_value(<<"headers">>, Props) of - undefined -> []; - {H1} -> H1 - end, - rewrite_body(Rewrite) - ) - end; -do_rewrite( - #httpd{ - method = Method, - path_parts = [_DbName, <<"_design">>, _DesignName, _Rewrite | PathParts], - mochi_req = MochiReq - } = Req, - Rules -) when is_list(Rules) -> - % create dispatch list from rules - Prefix = path_prefix(Req), - QueryList = lists:map(fun decode_query_value/1, chttpd:qs(Req)), - - DispatchList = [make_rule(Rule) || {Rule} <- Rules], - Method1 = couch_util:to_binary(Method), - - %% get raw path by matching url to a rule. - RawPath = - case - try_bind_path( - DispatchList, - Method1, - PathParts, - QueryList - ) - of - no_dispatch_path -> - throw(not_found); - {NewPathParts, Bindings} -> - Parts = [quote_plus(X) || X <- NewPathParts], - - % build new path, reencode query args, eventually convert - % them to json - Bindings1 = maybe_encode_bindings(Bindings), - Path = iolist_to_binary([ - string:join(Parts, [?SEPARATOR]), - [["?", mochiweb_util:urlencode(Bindings1)] || Bindings1 =/= []] - ]), - - % if path is relative detect it and rewrite path - safe_relative_path(Prefix, Path) - end, - - % normalize final path (fix levels "." and "..") - RawPath1 = ?b2l(normalize_path(RawPath)), - - couch_log:debug("rewrite to ~p ~n", [RawPath1]), - - % build a new mochiweb request - MochiReq1 = mochiweb_request:new( - MochiReq:get(socket), - MochiReq:get(method), - RawPath1, - MochiReq:get(version), - MochiReq:get(headers) - ), - - % cleanup, It force mochiweb to reparse raw uri. - MochiReq1:cleanup(), - - chttpd:handle_request_int(MochiReq1). - -rewrite_method(#httpd{method = Method}, {Props}) -> - DefaultMethod = couch_util:to_binary(Method), - couch_util:get_value(<<"method">>, Props, DefaultMethod). - -rewrite_path(#httpd{} = Req, {Props} = Rewrite) -> - Prefix = path_prefix(Req), - RewritePath = - case couch_util:get_value(<<"path">>, Props) of - undefined -> - throw({<<"rewrite_error">>, <<"Rewrite result must produce a new path.">>}); - P -> - P - end, - SafeRelativePath = safe_relative_path(Prefix, RewritePath), - NormalizedPath = normalize_path(SafeRelativePath), - QueryParams = rewrite_query_params(Req, Rewrite), - case QueryParams of - <<"">> -> - NormalizedPath; - QueryParams -> - <> - end. - -rewrite_query_params(#httpd{} = Req, {Props}) -> - RequestQS = chttpd:qs(Req), - RewriteQS = - case couch_util:get_value(<<"query">>, Props) of - undefined -> RequestQS; - {V} -> V - end, - RewriteQSEsc = [{chttpd:quote(K), chttpd:quote(V)} || {K, V} <- RewriteQS], - iolist_to_binary(string:join([[K, "=", V] || {K, V} <- RewriteQSEsc], "&")). - -rewrite_headers(#httpd{mochi_req = MochiReq}, {Props}) -> - case couch_util:get_value(<<"headers">>, Props) of - undefined -> - MochiReq:get(headers); - {H} -> - mochiweb_headers:enter_from_list( - lists:map(fun({Key, Val}) -> {?b2l(Key), ?b2l(Val)} end, H), - MochiReq:get(headers) - ) - end. - -rewrite_body({Props}) -> - Body = - case couch_util:get_value(<<"body">>, Props) of - undefined -> erlang:get(mochiweb_request_body); - B -> B - end, - case Body of - undefined -> - []; - _ -> - erlang:put(mochiweb_request_body, Body), - Body - end. - -path_prefix(#httpd{path_parts = [DbName, <<"_design">>, DesignName | _]}) -> - EscapedDesignName = ?l2b(couch_util:url_encode(DesignName)), - EscapedDbName = ?l2b(couch_util:url_encode(DbName)), - DesignId = <<"_design/", EscapedDesignName/binary>>, - <<"/", EscapedDbName/binary, "/", DesignId/binary>>. - -safe_relative_path(Prefix, Path) -> - case mochiweb_util:safe_relative_path(?b2l(Path)) of - undefined -> - <>; - V0 -> - V1 = ?l2b(V0), - <> - end. - -quote_plus({bind, X}) -> - mochiweb_util:quote_plus(X); -quote_plus(X) -> - mochiweb_util:quote_plus(X). - -%% @doc Try to find a rule matching current url. If none is found -%% 404 error not_found is raised -try_bind_path([], _Method, _PathParts, _QueryList) -> - no_dispatch_path; -try_bind_path([Dispatch | Rest], Method, PathParts, QueryList) -> - [{PathParts1, Method1}, RedirectPath, QueryArgs, Formats] = Dispatch, - case bind_method(Method1, Method) of - true -> - case bind_path(PathParts1, PathParts, []) of - {ok, Remaining, Bindings} -> - Bindings1 = Bindings ++ QueryList, - % we parse query args from the rule and fill - % it eventually with bindings vars - QueryArgs1 = make_query_list( - QueryArgs, - Bindings1, - Formats, - [] - ), - % remove params in QueryLists1 that are already in - % QueryArgs1 - Bindings2 = lists:foldl( - fun({K, V}, Acc) -> - K1 = to_binding(K), - KV = - case couch_util:get_value(K1, QueryArgs1) of - undefined -> [{K1, V}]; - _V1 -> [] - end, - Acc ++ KV - end, - [], - Bindings1 - ), - - FinalBindings = Bindings2 ++ QueryArgs1, - NewPathParts = make_new_path( - RedirectPath, - FinalBindings, - Remaining, - [] - ), - {NewPathParts, FinalBindings}; - fail -> - try_bind_path(Rest, Method, PathParts, QueryList) - end; - false -> - try_bind_path(Rest, Method, PathParts, QueryList) - end. - -%% rewriting dynamically the quey list given as query member in -%% rewrites. Each value is replaced by one binding or an argument -%% passed in url. -make_query_list([], _Bindings, _Formats, Acc) -> - Acc; -make_query_list([{Key, {Value}} | Rest], Bindings, Formats, Acc) -> - Value1 = {Value}, - make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1} | Acc]); -make_query_list([{Key, Value} | Rest], Bindings, Formats, Acc) when is_binary(Value) -> - Value1 = replace_var(Value, Bindings, Formats), - make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1} | Acc]); -make_query_list([{Key, Value} | Rest], Bindings, Formats, Acc) when is_list(Value) -> - Value1 = replace_var(Value, Bindings, Formats), - make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value1} | Acc]); -make_query_list([{Key, Value} | Rest], Bindings, Formats, Acc) -> - make_query_list(Rest, Bindings, Formats, [{to_binding(Key), Value} | Acc]). - -replace_var(<<"*">> = Value, Bindings, Formats) -> - get_var(Value, Bindings, Value, Formats); -replace_var(<<":", Var/binary>> = Value, Bindings, Formats) -> - get_var(Var, Bindings, Value, Formats); -replace_var(Value, _Bindings, _Formats) when is_binary(Value) -> - Value; -replace_var(Value, Bindings, Formats) when is_list(Value) -> - lists:reverse( - lists:foldl( - fun - (<<":", Var/binary>> = Value1, Acc) -> - [get_var(Var, Bindings, Value1, Formats) | Acc]; - (Value1, Acc) -> - [Value1 | Acc] - end, - [], - Value - ) - ); -replace_var(Value, _Bindings, _Formats) -> - Value. - -maybe_json(Key, Value) -> - case - lists:member(Key, [ - <<"key">>, - <<"startkey">>, - <<"start_key">>, - <<"endkey">>, - <<"end_key">>, - <<"keys">> - ]) - of - true -> - ?JSON_ENCODE(Value); - false -> - Value - end. - -get_var(VarName, Props, Default, Formats) -> - VarName1 = to_binding(VarName), - Val = couch_util:get_value(VarName1, Props, Default), - maybe_format(VarName, Val, Formats). - -maybe_format(VarName, Value, Formats) -> - case couch_util:get_value(VarName, Formats) of - undefined -> - Value; - Format -> - format(Format, Value) - end. - -format(<<"int">>, Value) when is_integer(Value) -> - Value; -format(<<"int">>, Value) when is_binary(Value) -> - format(<<"int">>, ?b2l(Value)); -format(<<"int">>, Value) when is_list(Value) -> - case (catch list_to_integer(Value)) of - IntVal when is_integer(IntVal) -> - IntVal; - _ -> - Value - end; -format(<<"bool">>, Value) when is_binary(Value) -> - format(<<"bool">>, ?b2l(Value)); -format(<<"bool">>, Value) when is_list(Value) -> - case string:to_lower(Value) of - "true" -> true; - "false" -> false; - _ -> Value - end; -format(_Format, Value) -> - Value. - -%% doc: build new patch from bindings. bindings are query args -%% (+ dynamic query rewritten if needed) and bindings found in -%% bind_path step. -make_new_path([], _Bindings, _Remaining, Acc) -> - lists:reverse(Acc); -make_new_path([?MATCH_ALL], _Bindings, Remaining, Acc) -> - Acc1 = lists:reverse(Acc) ++ Remaining, - Acc1; -make_new_path([?MATCH_ALL | _Rest], _Bindings, Remaining, Acc) -> - Acc1 = lists:reverse(Acc) ++ Remaining, - Acc1; -make_new_path([{bind, P} | Rest], Bindings, Remaining, Acc) -> - P2 = - case couch_util:get_value({bind, P}, Bindings) of - undefined -> <<"undefined">>; - P1 -> iolist_to_binary(P1) - end, - make_new_path(Rest, Bindings, Remaining, [P2 | Acc]); -make_new_path([P | Rest], Bindings, Remaining, Acc) -> - make_new_path(Rest, Bindings, Remaining, [P | Acc]). - -%% @doc If method of the query fith the rule method. If the -%% method rule is '*', which is the default, all -%% request method will bind. It allows us to make rules -%% depending on HTTP method. -bind_method(?MATCH_ALL, _Method) -> - true; -bind_method({bind, Method}, Method) -> - true; -bind_method(_, _) -> - false. - -%% @doc bind path. Using the rule from we try to bind variables given -%% to the current url by pattern matching -bind_path([], [], Bindings) -> - {ok, [], Bindings}; -bind_path([?MATCH_ALL], Rest, Bindings) when is_list(Rest) -> - {ok, Rest, Bindings}; -bind_path(_, [], _) -> - fail; -bind_path([{bind, Token} | RestToken], [Match | RestMatch], Bindings) -> - bind_path(RestToken, RestMatch, [{{bind, Token}, Match} | Bindings]); -bind_path([Token | RestToken], [Token | RestMatch], Bindings) -> - bind_path(RestToken, RestMatch, Bindings); -bind_path(_, _, _) -> - fail. - -%% normalize path. -normalize_path(Path) when is_binary(Path) -> - normalize_path(?b2l(Path)); -normalize_path(Path) when is_list(Path) -> - Segments = normalize_path1(string:tokens(Path, "/"), []), - NormalizedPath = string:join(Segments, [?SEPARATOR]), - iolist_to_binary(["/", NormalizedPath]). - -normalize_path1([], Acc) -> - lists:reverse(Acc); -normalize_path1([".." | Rest], Acc) -> - Acc1 = - case Acc of - [] -> [".." | Acc]; - [T | _] when T =:= ".." -> [".." | Acc]; - [_ | R] -> R - end, - normalize_path1(Rest, Acc1); -normalize_path1(["." | Rest], Acc) -> - normalize_path1(Rest, Acc); -normalize_path1([Path | Rest], Acc) -> - normalize_path1(Rest, [Path | Acc]). - -%% @doc transform json rule in erlang for pattern matching -make_rule(Rule) -> - Method = - case couch_util:get_value(<<"method">>, Rule) of - undefined -> ?MATCH_ALL; - M -> to_binding(M) - end, - QueryArgs = - case couch_util:get_value(<<"query">>, Rule) of - undefined -> []; - {Args} -> Args - end, - FromParts = - case couch_util:get_value(<<"from">>, Rule) of - undefined -> [?MATCH_ALL]; - From -> parse_path(From) - end, - ToParts = - case couch_util:get_value(<<"to">>, Rule) of - undefined -> - throw({error, invalid_rewrite_target}); - To -> - parse_path(To) - end, - Formats = - case couch_util:get_value(<<"formats">>, Rule) of - undefined -> []; - {Fmts} -> Fmts - end, - [{FromParts, Method}, ToParts, QueryArgs, Formats]. - -parse_path(Path) -> - {ok, SlashRE} = re:compile(<<"\\/">>), - path_to_list(re:split(Path, SlashRE), [], 0). - -%% @doc convert a path rule (from or to) to an erlang list -%% * and path variable starting by ":" are converted -%% in erlang atom. -path_to_list([], Acc, _DotDotCount) -> - lists:reverse(Acc); -path_to_list([<<>> | R], Acc, DotDotCount) -> - path_to_list(R, Acc, DotDotCount); -path_to_list([<<"*">> | R], Acc, DotDotCount) -> - path_to_list(R, [?MATCH_ALL | Acc], DotDotCount); -path_to_list([<<"..">> | R], Acc, DotDotCount) when DotDotCount == 2 -> - case chttpd_util:get_chttpd_config_boolean("secure_rewrites", true) of - false -> - path_to_list(R, [<<"..">> | Acc], DotDotCount + 1); - true -> - couch_log:notice( - "insecure_rewrite_rule ~p blocked", - [lists:reverse(Acc) ++ [<<"..">>] ++ R] - ), - throw({insecure_rewrite_rule, "too many ../.. segments"}) - end; -path_to_list([<<"..">> | R], Acc, DotDotCount) -> - path_to_list(R, [<<"..">> | Acc], DotDotCount + 1); -path_to_list([P | R], Acc, DotDotCount) -> - P1 = - case P of - <<":", Var/binary>> -> - to_binding(Var); - _ -> - P - end, - path_to_list(R, [P1 | Acc], DotDotCount). - -maybe_encode_bindings([]) -> - []; -maybe_encode_bindings(Props) -> - lists:foldl( - fun - ({{bind, <<"*">>}, _V}, Acc) -> - Acc; - ({{bind, K}, V}, Acc) -> - V1 = iolist_to_binary(maybe_json(K, V)), - [{K, V1} | Acc] - end, - [], - Props - ). - -decode_query_value({K, V}) -> - case - lists:member(K, [ - "key", - "startkey", - "start_key", - "endkey", - "end_key", - "keys" - ]) - of - true -> - {to_binding(K), ?JSON_DECODE(V)}; - false -> - {to_binding(K), ?l2b(V)} - end. - -to_binding({bind, V}) -> - {bind, V}; -to_binding(V) when is_list(V) -> - to_binding(?l2b(V)); -to_binding(V) -> - {bind, V}. diff --git a/src/chttpd/src/chttpd_show.erl b/src/chttpd/src/chttpd_show.erl deleted file mode 100644 index e798a98d6..000000000 --- a/src/chttpd/src/chttpd_show.erl +++ /dev/null @@ -1,331 +0,0 @@ -% 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. - --module(chttpd_show). - --export([handle_doc_show_req/3, handle_doc_update_req/3, handle_view_list_req/3]). - --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). - -% /db/_design/foo/_show/bar/docid -% show converts a json doc to a response of any content-type. -% it looks up the doc an then passes it to the query server. -% then it sends the response from the query server to the http client. - -maybe_open_doc(Db, DocId, Options) -> - case fabric:open_doc(Db, DocId, Options) of - {ok, Doc} -> - chttpd_stats:incr_reads(), - Doc; - {not_found, _} -> - nil - end. - -handle_doc_show_req( - #httpd{ - path_parts = [_, _, _, _, ShowName, DocId] - } = Req, - Db, - DDoc -) -> - % open the doc - Options = [conflicts, {user_ctx, Req#httpd.user_ctx}], - Doc = maybe_open_doc(Db, DocId, Options), - - % we don't handle revs here b/c they are an internal api - % returns 404 if there is no doc with DocId - handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId); -handle_doc_show_req( - #httpd{ - path_parts = [_, _, _, _, ShowName, DocId | Rest] - } = Req, - Db, - DDoc -) -> - DocParts = [DocId | Rest], - DocId1 = ?l2b(string:join([?b2l(P) || P <- DocParts], "/")), - - % open the doc - Options = [conflicts, {user_ctx, Req#httpd.user_ctx}], - Doc = maybe_open_doc(Db, DocId1, Options), - - % we don't handle revs here b/c they are an internal api - % pass 404 docs to the show function - handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId1); -handle_doc_show_req( - #httpd{ - path_parts = [_, _, _, _, ShowName] - } = Req, - Db, - DDoc -) -> - % with no docid the doc is nil - handle_doc_show(Req, Db, DDoc, ShowName, nil); -handle_doc_show_req(Req, _Db, _DDoc) -> - chttpd:send_error(Req, 404, <<"show_error">>, <<"Invalid path.">>). - -handle_doc_show(Req, Db, DDoc, ShowName, Doc) -> - handle_doc_show(Req, Db, DDoc, ShowName, Doc, null). - -handle_doc_show(Req, Db, DDoc, ShowName, Doc, DocId) -> - %% Will throw an exception if the _show handler is missing - couch_util:get_nested_json_value(DDoc#doc.body, [<<"shows">>, ShowName]), - % get responder for ddoc/showname - CurrentEtag = show_etag(Req, Doc, DDoc, []), - chttpd:etag_respond(Req, CurrentEtag, fun() -> - JsonReq = chttpd_external:json_req_obj(Req, Db, DocId), - JsonDoc = couch_query_servers:json_doc(Doc), - [<<"resp">>, ExternalResp] = - couch_query_servers:ddoc_prompt( - DDoc, - [<<"shows">>, ShowName], - [JsonDoc, JsonReq] - ), - JsonResp = apply_etag(ExternalResp, CurrentEtag), - chttpd_external:send_external_response(Req, JsonResp) - end). - -show_etag(#httpd{user_ctx = UserCtx} = Req, Doc, DDoc, More) -> - Accept = chttpd:header_value(Req, "Accept"), - DocPart = - case Doc of - nil -> nil; - Doc -> chttpd:doc_etag(Doc) - end, - couch_httpd:make_etag({ - couch_httpd:doc_etag(DDoc), DocPart, Accept, UserCtx#user_ctx.roles, More - }). - -% /db/_design/foo/update/bar/docid -% updates a doc based on a request -% handle_doc_update_req(#httpd{method = 'GET'}=Req, _Db, _DDoc) -> -% % anything but GET -% send_method_not_allowed(Req, "POST,PUT,DELETE,ETC"); - -handle_doc_update_req( - #httpd{ - path_parts = [_, _, _, _, UpdateName] - } = Req, - Db, - DDoc -) -> - send_doc_update_response(Req, Db, DDoc, UpdateName, nil, null); -handle_doc_update_req( - #httpd{ - path_parts = [_, _, _, _, UpdateName | DocIdParts] - } = Req, - Db, - DDoc -) -> - DocId = ?l2b(string:join([?b2l(P) || P <- DocIdParts], "/")), - Options = [conflicts, {user_ctx, Req#httpd.user_ctx}], - Doc = maybe_open_doc(Db, DocId, Options), - send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId); -handle_doc_update_req(Req, _Db, _DDoc) -> - chttpd:send_error(Req, 404, <<"update_error">>, <<"Invalid path.">>). - -send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) -> - %% Will throw an exception if the _update handler is missing - couch_util:get_nested_json_value(DDoc#doc.body, [<<"updates">>, UpdateName]), - JsonReq = chttpd_external:json_req_obj(Req, Db, DocId), - JsonDoc = couch_query_servers:json_doc(Doc), - Cmd = [<<"updates">>, UpdateName], - W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))), - UpdateResp = couch_query_servers:ddoc_prompt(DDoc, Cmd, [JsonDoc, JsonReq]), - JsonResp = - case UpdateResp of - [<<"up">>, {NewJsonDoc}, {JsonResp0}] -> - case chttpd:header_value(Req, "X-Couch-Full-Commit", "false") of - "true" -> - Options = [full_commit, {user_ctx, Req#httpd.user_ctx}, {w, W}]; - _ -> - Options = [{user_ctx, Req#httpd.user_ctx}, {w, W}] - end, - NewDoc = couch_db:doc_from_json_obj_validate(Db, {NewJsonDoc}), - couch_doc:validate_docid(NewDoc#doc.id), - {UpdateResult, NewRev} = fabric:update_doc(Db, NewDoc, Options), - chttpd_stats:incr_writes(), - NewRevStr = couch_doc:rev_to_str(NewRev), - case {UpdateResult, NewRev} of - {ok, _} -> - Code = 201; - {accepted, _} -> - Code = 202 - end, - {JsonResp1} = apply_headers(JsonResp0, [ - {<<"X-Couch-Update-NewRev">>, NewRevStr}, - {<<"X-Couch-Id">>, couch_util:url_encode(NewDoc#doc.id)} - ]), - {[{<<"code">>, Code} | JsonResp1]}; - [<<"up">>, _Other, {JsonResp0}] -> - {[{<<"code">>, 200} | JsonResp0]} - end, - % todo set location field - chttpd_external:send_external_response(Req, JsonResp). - -% view-list request with view and list from same design doc. -handle_view_list_req( - #httpd{ - method = Method, - path_parts = [_, _, DesignName, _, ListName, ViewName] - } = Req, - Db, - DDoc -) when - Method =:= 'GET' orelse Method =:= 'OPTIONS' --> - Keys = chttpd:qs_json_value(Req, "keys", undefined), - handle_view_list(Req, Db, DDoc, ListName, {DesignName, ViewName}, Keys); -% view-list request with view and list from different design docs. -handle_view_list_req( - #httpd{ - method = Method, - path_parts = [_, _, _, _, ListName, DesignName, ViewName] - } = Req, - Db, - DDoc -) when - Method =:= 'GET' orelse Method =:= 'OPTIONS' --> - Keys = chttpd:qs_json_value(Req, "keys", undefined), - handle_view_list(Req, Db, DDoc, ListName, {DesignName, ViewName}, Keys); -handle_view_list_req(#httpd{method = Method} = Req, _Db, _DDoc) when - Method =:= 'GET' orelse Method =:= 'OPTIONS' --> - chttpd:send_error(Req, 404, <<"list_error">>, <<"Invalid path.">>); -handle_view_list_req( - #httpd{ - method = 'POST', - path_parts = [_, _, DesignName, _, ListName, ViewName] - } = Req, - Db, - DDoc -) -> - chttpd:validate_ctype(Req, "application/json"), - {Props} = chttpd:json_body(Req), - Keys = proplists:get_value(<<"keys">>, Props, undefined), - handle_view_list( - Req#httpd{req_body = {Props}}, - Db, - DDoc, - ListName, - {DesignName, ViewName}, - Keys - ); -handle_view_list_req( - #httpd{ - method = 'POST', - path_parts = [_, _, _, _, ListName, DesignName, ViewName] - } = Req, - Db, - DDoc -) -> - chttpd:validate_ctype(Req, "application/json"), - {Props} = chttpd:json_body(Req), - Keys = proplists:get_value(<<"keys">>, Props, undefined), - handle_view_list( - Req#httpd{req_body = {Props}}, - Db, - DDoc, - ListName, - {DesignName, ViewName}, - Keys - ); -handle_view_list_req(#httpd{method = 'POST'} = Req, _Db, _DDoc) -> - chttpd:send_error(Req, 404, <<"list_error">>, <<"Invalid path.">>); -handle_view_list_req(Req, _Db, _DDoc) -> - chttpd:send_method_not_allowed(Req, "GET,POST,HEAD"). - -handle_view_list(Req, Db, DDoc, LName, {ViewDesignName, ViewName}, Keys) -> - %% Will throw an exception if the _list handler is missing - couch_util:get_nested_json_value(DDoc#doc.body, [<<"lists">>, LName]), - DbName = couch_db:name(Db), - {ok, VDoc} = ddoc_cache:open(DbName, <<"_design/", ViewDesignName/binary>>), - CB = fun list_cb/2, - QueryArgs = couch_mrview_http:parse_body_and_query(Req, Keys), - Options = [{user_ctx, Req#httpd.user_ctx}], - couch_query_servers:with_ddoc_proc(DDoc, fun(QServer) -> - Acc = #lacc{ - lname = LName, - req = Req, - qserver = QServer, - db = Db - }, - case ViewName of - <<"_all_docs">> -> - fabric:all_docs(Db, Options, CB, Acc, QueryArgs); - _ -> - fabric:query_view( - Db, - Options, - VDoc, - ViewName, - CB, - Acc, - QueryArgs - ) - end - end). - -list_cb({row, Row} = Msg, Acc) -> - case lists:keymember(doc, 1, Row) of - true -> chttpd_stats:incr_reads(); - false -> ok - end, - chttpd_stats:incr_rows(), - couch_mrview_show:list_cb(Msg, Acc); -list_cb(Msg, Acc) -> - couch_mrview_show:list_cb(Msg, Acc). - -% Maybe this is in the proplists API -% todo move to couch_util -json_apply_field(H, {L}) -> - json_apply_field(H, L, []). -json_apply_field({Key, NewValue}, [{Key, _OldVal} | Headers], Acc) -> - % drop matching keys - json_apply_field({Key, NewValue}, Headers, Acc); -json_apply_field({Key, NewValue}, [{OtherKey, OtherVal} | Headers], Acc) -> - % something else is next, leave it alone. - json_apply_field({Key, NewValue}, Headers, [{OtherKey, OtherVal} | Acc]); -json_apply_field({Key, NewValue}, [], Acc) -> - % end of list, add ours - {[{Key, NewValue} | Acc]}. - -apply_etag(JsonResp, undefined) -> - JsonResp; -apply_etag({ExternalResponse}, CurrentEtag) -> - % Here we embark on the delicate task of replacing or creating the - % headers on the JsonResponse object. We need to control the Etag and - % Vary headers. If the external function controls the Etag, we'd have to - % run it to check for a match, which sort of defeats the purpose. - apply_headers(ExternalResponse, [ - {<<"ETag">>, CurrentEtag}, - {<<"Vary">>, <<"Accept">>} - ]). - -apply_headers(JsonResp, []) -> - JsonResp; -apply_headers(JsonResp, NewHeaders) -> - case couch_util:get_value(<<"headers">>, JsonResp) of - undefined -> - {[{<<"headers">>, {NewHeaders}} | JsonResp]}; - JsonHeaders -> - Headers = apply_headers1(JsonHeaders, NewHeaders), - NewKV = {<<"headers">>, Headers}, - {lists:keyreplace(<<"headers">>, 1, JsonResp, NewKV)} - end. -apply_headers1(JsonHeaders, [{Key, Value} | Rest]) -> - NewJsonHeaders = json_apply_field({Key, Value}, JsonHeaders), - apply_headers1(NewJsonHeaders, Rest); -apply_headers1(JsonHeaders, []) -> - JsonHeaders. diff --git a/src/chttpd/src/chttpd_stats.erl b/src/chttpd/src/chttpd_stats.erl deleted file mode 100644 index f6eb01659..000000000 --- a/src/chttpd/src/chttpd_stats.erl +++ /dev/null @@ -1,96 +0,0 @@ -% 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. - --module(chttpd_stats). - -% for the stacktrace macro only so far --include_lib("couch/include/couch_db.hrl"). - --export([ - init/0, - report/2, - - incr_reads/0, - incr_reads/1, - - incr_writes/0, - incr_writes/1, - - incr_rows/0, - incr_rows/1 -]). - --record(st, { - reads = 0, - writes = 0, - rows = 0 -}). - --define(KEY, chttpd_stats). - -init() -> - put(?KEY, #st{}). - -report(HttpReq, HttpResp) -> - try - case get(?KEY) of - #st{} = St -> - report(HttpReq, HttpResp, St); - _ -> - ok - end - catch ?STACKTRACE(T, R, S) - Fmt = "Failed to report chttpd request stats: ~p:~p ~p", - couch_log:error(Fmt, [T, R, S]) - end. - -report(HttpReq, HttpResp, St) -> - case config:get("chttpd", "stats_reporter") of - undefined -> - ok; - ModStr -> - Mod = list_to_existing_atom(ModStr), - #st{ - reads = Reads, - writes = Writes, - rows = Rows - } = St, - Mod:report(HttpReq, HttpResp, Reads, Writes, Rows) - end. - -incr_reads() -> - incr(#st.reads, 1). - -incr_reads(N) when is_integer(N), N >= 0 -> - incr(#st.reads, N). - -incr_writes() -> - incr(#st.writes, 1). - -incr_writes(N) when is_integer(N), N >= 0 -> - incr(#st.writes, N). - -incr_rows() -> - incr(#st.rows, 1). - -incr_rows(N) when is_integer(N), N >= 0 -> - incr(#st.rows, N). - -incr(Idx, Count) -> - case get(?KEY) of - #st{} = St -> - Total = element(Idx, St) + Count, - NewSt = setelement(Idx, St, Total), - put(?KEY, NewSt); - _ -> - ok - end. diff --git a/src/chttpd/src/chttpd_sup.erl b/src/chttpd/src/chttpd_sup.erl deleted file mode 100644 index ea4e62f80..000000000 --- a/src/chttpd/src/chttpd_sup.erl +++ /dev/null @@ -1,178 +0,0 @@ -% 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. - --module(chttpd_sup). --behaviour(supervisor). --vsn(1). - --behaviour(config_listener). - --export([init/1]). - --export([start_link/1]). - --export([handle_config_change/5, handle_config_terminate/3]). - -%% Helper macro for declaring children of supervisor --define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 100, Type, [I]}). --define(DEFAULT_BACKLOG, 512). --define(DEFAULT_SERVER_OPTIONS, "[{recbuf, undefined}]"). - -start_link(Args) -> - case supervisor:start_link({local, ?MODULE}, ?MODULE, Args) of - {ok, _} = Resp -> - notify_started(), - notify_uris(), - write_uris(), - Resp; - Else -> - notify_error(Else), - Else - end. - -init([]) -> - Children = [ - { - config_listener_mon, - {config_listener_mon, start_link, [?MODULE, settings()]}, - permanent, - 5000, - worker, - [config_listener_mon] - }, - ?CHILD(chttpd, worker), - ?CHILD(chttpd_auth_cache, worker), - {chttpd_auth_cache_lru, {ets_lru, start_link, [chttpd_auth_cache_lru, lru_opts()]}, - permanent, 5000, worker, [ets_lru]} - ], - - {ok, {{one_for_one, 3, 10}, couch_epi:register_service(chttpd_epi, Children)}}. - -handle_config_change("chttpd", "bind_address", Value, _, Settings) -> - maybe_replace(bind_address, Value, Settings); -handle_config_change("chttpd", "port", Value, _, Settings) -> - maybe_replace(port, Value, Settings); -handle_config_change("chttpd", "backlog", Value, _, Settings) -> - maybe_replace(backlog, Value, Settings); -handle_config_change("chttpd", "server_options", Value, _, Settings) -> - maybe_replace(server_options, Value, Settings); -handle_config_change(_, _, _, _, Settings) -> - {ok, Settings}. - -handle_config_terminate(_Server, _Reason, _State) -> - ok. - -settings() -> - [ - {bind_address, config:get("chttpd", "bind_address")}, - {port, config:get("chttpd", "port")}, - {backlog, config:get_integer("chttpd", "backlog", ?DEFAULT_BACKLOG)}, - {server_options, - config:get( - "chttpd", - "server_options", - ?DEFAULT_SERVER_OPTIONS - )} - ]. - -maybe_replace(Key, Value, Settings) -> - case couch_util:get_value(Key, Settings) of - Value -> - {ok, Settings}; - _ -> - chttpd:stop(), - {ok, lists:keyreplace(Key, 1, Settings, {Key, Value})} - end. - -lru_opts() -> - lists:foldl(fun append_if_set/2, [], [ - {max_objects, config:get_integer("chttpd_auth_cache", "max_objects", 0)}, - {max_size, config:get_integer("chttpd_auth_cache", "max_size", 104857600)}, - {max_lifetime, config:get_integer("chttpd_auth_cache", "max_lifetime", 600000)} - ]). - -append_if_set({Key, Value}, Opts) when Value > 0 -> - [{Key, Value} | Opts]; -append_if_set({_Key, 0}, Opts) -> - Opts; -append_if_set({Key, Value}, Opts) -> - couch_log:error( - "The value for `~s` should be string convertable " - "to integer which is >= 0 (got `~p`)", - [Key, Value] - ), - Opts. - -notify_started() -> - couch_log:info("Apache CouchDB has started. Time to relax.~n", []). - -notify_error(Error) -> - couch_log:error("Error starting Apache CouchDB:~n~n ~p~n~n", [Error]). - -notify_uris() -> - lists:foreach( - fun(Uri) -> - couch_log:info("Apache CouchDB has started on ~s", [Uri]) - end, - get_uris() - ). - -write_uris() -> - case config:get("couchdb", "uri_file", undefined) of - undefined -> - ok; - UriFile -> - Lines = [io_lib:format("~s~n", [Uri]) || Uri <- get_uris()], - write_file(UriFile, Lines) - end. - -get_uris() -> - Ip = config:get("chttpd", "bind_address"), - lists:flatmap( - fun(Uri) -> - case get_uri(Uri, Ip) of - undefined -> []; - Else -> [Else] - end - end, - [chttpd, couch_httpd, https] - ). - -get_uri(Name, Ip) -> - case get_port(Name) of - undefined -> - undefined; - Port -> - io_lib:format("~s://~s:~w/", [get_scheme(Name), Ip, Port]) - end. - -get_scheme(chttpd) -> "http"; -get_scheme(couch_httpd) -> "http"; -get_scheme(https) -> "https". - -get_port(Name) -> - try - mochiweb_socket_server:get(Name, port) - catch - exit:{noproc, _} -> - undefined - end. - -write_file(FileName, Contents) -> - case file:write_file(FileName, Contents) of - ok -> - ok; - {error, Reason} -> - Args = [FileName, file:format_error(Reason)], - couch_log:error("Failed ot write ~s :: ~s", Args), - throw({error, Reason}) - end. diff --git a/src/chttpd/src/chttpd_test_util.erl b/src/chttpd/src/chttpd_test_util.erl deleted file mode 100644 index 8a849acda..000000000 --- a/src/chttpd/src/chttpd_test_util.erl +++ /dev/null @@ -1,26 +0,0 @@ -% 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. - --module(chttpd_test_util). - --export([start_couch/0, start_couch/1, stop_couch/1]). - --include_lib("couch/include/couch_eunit.hrl"). - -start_couch() -> - start_couch(?CONFIG_CHAIN). - -start_couch(IniFiles) -> - test_util:start_couch(IniFiles, [chttpd]). - -stop_couch(Ctx) -> - test_util:stop_couch(Ctx). diff --git a/src/chttpd/src/chttpd_util.erl b/src/chttpd/src/chttpd_util.erl deleted file mode 100644 index 955beca57..000000000 --- a/src/chttpd/src/chttpd_util.erl +++ /dev/null @@ -1,112 +0,0 @@ -% 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. - --module(chttpd_util). - --export([ - get_chttpd_config/1, - get_chttpd_config/2, - get_chttpd_config_integer/2, - get_chttpd_config_boolean/2, - get_chttpd_auth_config/1, - get_chttpd_auth_config/2, - get_chttpd_auth_config_integer/2, - get_chttpd_auth_config_boolean/2, - maybe_add_csp_header/3, - get_db_info/1 -]). - -get_chttpd_config(Key) -> - config:get("chttpd", Key, config:get("httpd", Key)). - -get_chttpd_config(Key, Default) -> - config:get("chttpd", Key, config:get("httpd", Key, Default)). - -get_chttpd_config_integer(Key, Default) -> - config:get_integer( - "chttpd", - Key, - config:get_integer("httpd", Key, Default) - ). - -get_chttpd_config_boolean(Key, Default) -> - config:get_boolean( - "chttpd", - Key, - config:get_boolean("httpd", Key, Default) - ). - -get_chttpd_auth_config(Key) -> - config:get("chttpd_auth", Key, config:get("couch_httpd_auth", Key)). - -get_chttpd_auth_config(Key, Default) -> - config:get( - "chttpd_auth", - Key, - config:get("couch_httpd_auth", Key, Default) - ). - -get_chttpd_auth_config_integer(Key, Default) -> - config:get_integer( - "chttpd_auth", - Key, - config:get_integer("couch_httpd_auth", Key, Default) - ). - -get_chttpd_auth_config_boolean(Key, Default) -> - config:get_boolean( - "chttpd_auth", - Key, - config:get_boolean("couch_httpd_auth", Key, Default) - ). - -maybe_add_csp_header(Component, OriginalHeaders, DefaultHeaderValue) -> - Enabled = config:get_boolean("csp", Component ++ "_enable", true), - case Enabled of - true -> - HeaderValue = config:get("csp", Component ++ "_header_value", DefaultHeaderValue), - % As per https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#multiple_content_security_policies - % The top most CSP header defines the most open policy, - % subsequent CSP headers set by show/list functions can - % only further restrict the policy. - % - % Ours goes on top and we don’t have to worry about additional - % headers set by users. - [{"Content-Security-Policy", HeaderValue} | OriginalHeaders]; - false -> - % Fallback for old config vars - case Component of - "utils" -> - handle_legacy_config(OriginalHeaders, DefaultHeaderValue); - _ -> - OriginalHeaders - end - end. - -handle_legacy_config(OriginalHeaders, DefaultHeaderValue) -> - LegacyUtilsEnabled = config:get_boolean("csp", "enable", true), - case LegacyUtilsEnabled of - true -> - LegacyUtilsHeaderValue = config:get("csp", "header_value", DefaultHeaderValue), - [{"Content-Security-Policy", LegacyUtilsHeaderValue} | OriginalHeaders]; - false -> - OriginalHeaders - end. - -get_db_info(DbName) -> - Timeout = fabric_util:request_timeout(), - IsolatedFun = fun() -> fabric:get_db_info(DbName) end, - try - fabric_util:isolate(IsolatedFun, Timeout) - catch - _Tag:Error -> {error, Error} - end. diff --git a/src/chttpd/src/chttpd_view.erl b/src/chttpd/src/chttpd_view.erl deleted file mode 100644 index 1d721d189..000000000 --- a/src/chttpd/src/chttpd_view.erl +++ /dev/null @@ -1,215 +0,0 @@ -% 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. - --module(chttpd_view). --include_lib("couch/include/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). - --export([handle_view_req/3, handle_temp_view_req/2]). - -multi_query_view(Req, Db, DDoc, ViewName, Queries) -> - Args0 = couch_mrview_http:parse_params(Req, undefined), - {ok, #mrst{views = Views}} = couch_mrview_util:ddoc_to_mrst(Db, DDoc), - Args1 = couch_mrview_util:set_view_type(Args0, ViewName, Views), - ArgQueries = lists:map( - fun({Query}) -> - QueryArg = couch_mrview_http:parse_params( - Query, - undefined, - Args1, - [decoded] - ), - QueryArg1 = couch_mrview_util:set_view_type(QueryArg, ViewName, Views), - fabric_util:validate_args(Db, DDoc, QueryArg1) - end, - Queries - ), - Options = [{user_ctx, Req#httpd.user_ctx}], - VAcc0 = #vacc{db = Db, req = Req, prepend = "\r\n"}, - FirstChunk = "{\"results\":[", - {ok, Resp0} = chttpd:start_delayed_json_response(VAcc0#vacc.req, 200, [], FirstChunk), - VAcc1 = VAcc0#vacc{resp = Resp0}, - VAcc2 = lists:foldl( - fun(Args, Acc0) -> - {ok, Acc1} = fabric:query_view( - Db, - Options, - DDoc, - ViewName, - fun view_cb/2, - Acc0, - Args - ), - Acc1 - end, - VAcc1, - ArgQueries - ), - {ok, Resp1} = chttpd:send_delayed_chunk(VAcc2#vacc.resp, "\r\n]}"), - chttpd:end_delayed_json_response(Resp1). - -design_doc_post_view(Req, Props, Db, DDoc, ViewName, Keys) -> - Args = couch_mrview_http:parse_body_and_query(Req, Props, Keys), - fabric_query_view(Db, Req, DDoc, ViewName, Args). - -design_doc_view(Req, Db, DDoc, ViewName, Keys) -> - Args = couch_mrview_http:parse_params(Req, Keys), - fabric_query_view(Db, Req, DDoc, ViewName, Args). - -fabric_query_view(Db, Req, DDoc, ViewName, Args) -> - Max = chttpd:chunked_response_buffer_size(), - VAcc = #vacc{db = Db, req = Req, threshold = Max}, - Options = [{user_ctx, Req#httpd.user_ctx}], - {ok, Resp} = fabric:query_view( - Db, - Options, - DDoc, - ViewName, - fun view_cb/2, - VAcc, - Args - ), - {ok, Resp#vacc.resp}. - -view_cb({row, Row} = Msg, Acc) -> - case lists:keymember(doc, 1, Row) of - true -> chttpd_stats:incr_reads(); - false -> ok - end, - chttpd_stats:incr_rows(), - couch_mrview_http:view_cb(Msg, Acc); -view_cb(Msg, Acc) -> - couch_mrview_http:view_cb(Msg, Acc). - -handle_view_req( - #httpd{ - method = 'POST', - path_parts = [_, _, _, _, ViewName, <<"queries">>] - } = Req, - Db, - DDoc -) -> - chttpd:validate_ctype(Req, "application/json"), - Props = couch_httpd:json_body_obj(Req), - case couch_mrview_util:get_view_queries(Props) of - undefined -> - throw({bad_request, <<"POST body must include `queries` parameter.">>}); - Queries -> - multi_query_view(Req, Db, DDoc, ViewName, Queries) - end; -handle_view_req( - #httpd{path_parts = [_, _, _, _, _, <<"queries">>]} = Req, - _Db, - _DDoc -) -> - chttpd:send_method_not_allowed(Req, "POST"); -handle_view_req( - #httpd{ - method = 'GET', - path_parts = [_, _, _, _, ViewName] - } = Req, - Db, - DDoc -) -> - couch_stats:increment_counter([couchdb, httpd, view_reads]), - Keys = chttpd:qs_json_value(Req, "keys", undefined), - design_doc_view(Req, Db, DDoc, ViewName, Keys); -handle_view_req( - #httpd{ - method = 'POST', - path_parts = [_, _, _, _, ViewName] - } = Req, - Db, - DDoc -) -> - chttpd:validate_ctype(Req, "application/json"), - Props = couch_httpd:json_body_obj(Req), - assert_no_queries_param(couch_mrview_util:get_view_queries(Props)), - Keys = couch_mrview_util:get_view_keys(Props), - couch_stats:increment_counter([couchdb, httpd, view_reads]), - design_doc_post_view(Req, Props, Db, DDoc, ViewName, Keys); -handle_view_req(Req, _Db, _DDoc) -> - chttpd:send_method_not_allowed(Req, "GET,POST,HEAD"). - -handle_temp_view_req(Req, _Db) -> - Msg = <<"Temporary views are not supported in CouchDB">>, - chttpd:send_error(Req, 410, gone, Msg). - -% See https://github.com/apache/couchdb/issues/2168 -assert_no_queries_param(undefined) -> - ok; -assert_no_queries_param(_) -> - throw({ - bad_request, - "The `queries` parameter is no longer supported at this endpoint" - }). - --ifdef(TEST). - --include_lib("eunit/include/eunit.hrl"). - -check_multi_query_reduce_view_overrides_test_() -> - { - setup, - fun setup_all/0, - fun teardown_all/1, - { - foreach, - fun setup/0, - fun teardown/1, - [ - t_check_include_docs_throw_validation_error(), - t_check_user_can_override_individual_query_type() - ] - } - }. - -t_check_include_docs_throw_validation_error() -> - ?_test(begin - Req = #httpd{qs = []}, - Db = test_util:fake_db([{name, <<"foo">>}]), - Query = {[{<<"include_docs">>, true}]}, - Throw = {query_parse_error, <<"`include_docs` is invalid for reduce">>}, - ?assertThrow(Throw, multi_query_view(Req, Db, ddoc, <<"v">>, [Query])) - end). - -t_check_user_can_override_individual_query_type() -> - ?_test(begin - Req = #httpd{qs = []}, - Db = test_util:fake_db([{name, <<"foo">>}]), - Query = {[{<<"include_docs">>, true}, {<<"reduce">>, false}]}, - multi_query_view(Req, Db, ddoc, <<"v">>, [Query]), - ?assertEqual(1, meck:num_calls(chttpd, start_delayed_json_response, '_')) - end). - -setup_all() -> - Views = [#mrview{reduce_funs = [{<<"v">>, <<"_count">>}]}], - meck:expect(couch_mrview_util, ddoc_to_mrst, 2, {ok, #mrst{views = Views}}), - meck:expect(chttpd, start_delayed_json_response, 4, {ok, resp}), - meck:expect(fabric, query_view, 7, {ok, #vacc{}}), - meck:expect(chttpd, send_delayed_chunk, 2, {ok, resp}), - meck:expect(chttpd, end_delayed_json_response, 1, ok). - -teardown_all(_) -> - meck:unload(). - -setup() -> - meck:reset([ - chttpd, - couch_mrview_util, - fabric - ]). - -teardown(_) -> - ok. - --endif. diff --git a/src/chttpd/src/chttpd_xframe_options.erl b/src/chttpd/src/chttpd_xframe_options.erl deleted file mode 100644 index 15865057b..000000000 --- a/src/chttpd/src/chttpd_xframe_options.erl +++ /dev/null @@ -1,90 +0,0 @@ -% 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. - --module(chttpd_xframe_options). - --export([ - header/2, - header/3 -]). - --define(DENY, "DENY"). --define(SAMEORIGIN, "SAMEORIGIN"). --define(ALLOWFROM, "ALLOW-FROM "). - --include_lib("couch/include/couch_db.hrl"). - -% X-Frame-Options protects against clickjacking by limiting whether a response can be used in a -% ,