From 6a808d7ab0819b8ad0b4979b6e0af38f4148751a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 07:40:33 -0700 Subject: [PATCH] [WIP] bump eslint from 8.57.0 to 9.0.0 (#965) * chore(deps-dev): bump eslint from 8.57.0 to 9.0.0 * chore: migrate to eslint 9 * chore: format all files by prettier * chore: eslint rules * chore: remove vulnerable regex --- .changeset/rare-items-bow.md | 5 + .prettierrc | 3 +- .eslintrc.js => eslint.config.js | 23 +- package-lock.json | 592 +- package.json | 5 +- packages/cache-memory/src/index.spec.js | 6 +- .../src/data-provider/extend-controller.js | 19 +- .../data-provider/extend-controller.spec.js | 11 +- .../core/src/data-provider/extend-model.js | 104 +- .../src/data-provider/extend-model.spec.js | 90 +- .../helpers/compose-route-path.js | 12 +- .../helpers/compose-route-path.spec.js | 48 +- .../core/src/data-provider/helpers/index.js | 3 +- .../src/data-provider/helpers/route-joiner.js | 13 +- .../helpers/route-joiner.spec.js | 2 +- packages/core/src/data-provider/index.js | 115 +- packages/core/src/data-provider/index.spec.js | 85 +- .../core/src/data-provider/provider-route.js | 5 +- .../src/data-provider/provider-route.spec.js | 22 +- packages/core/src/index.js | 16 +- packages/core/src/index.spec.js | 55 +- .../src/generate-renderer/color-ramp.js | 19 +- .../src/generate-renderer/color-ramp.spec.js | 44 +- .../src/generate-renderer/create-symbol.js | 22 +- .../generate-renderer/create-symbol.spec.js | 45 +- .../src/generate-renderer/index.js | 55 +- .../src/generate-renderer/index.spec.js | 153 +- ...validate-classification-definition.spec.js | 81 +- .../src/helpers/data-type-utils.js | 21 +- .../src/helpers/data-type-utils.spec.js | 9 +- packages/featureserver/src/helpers/errors.js | 4 +- .../src/helpers/esri-units-lookup.js | 2 +- .../src/helpers/esri-units-lookup.spec.js | 2 +- .../src/helpers/fields/constants.js | 2 +- .../src/helpers/fields/constants.spec.js | 4 +- .../helpers/fields/esri-type-utils.spec.js | 16 +- .../src/helpers/fields/field-classes.js | 35 +- .../src/helpers/fields/field-classes.spec.js | 40 +- .../src/helpers/fields/fields.js | 50 +- .../src/helpers/fields/fields.spec.js | 262 +- .../featureserver/src/helpers/fields/index.js | 2 +- .../src/helpers/fields/layer-fields.js | 21 +- .../src/helpers/fields/layer-fields.spec.js | 463 +- .../src/helpers/fields/query-fields.js | 14 +- .../src/helpers/fields/query-fields.spec.js | 583 +- .../src/helpers/fields/statistics-fields.js | 76 +- .../helpers/fields/statistics-fields.spec.js | 160 +- .../src/helpers/get-collection-crs.js | 6 +- .../src/helpers/get-collection-crs.spec.js | 10 +- .../helpers/get-geometry-type-from-geojson.js | 15 +- .../get-geometry-type-from-geojson.spec.js | 25 +- .../src/helpers/get-spatial-reference.js | 6 +- .../src/helpers/get-spatial-reference.spec.js | 15 +- packages/featureserver/src/helpers/index.js | 8 +- .../src/helpers/is-geojson-table.js | 17 +- .../src/helpers/is-geojson-table.spec.js | 82 +- .../src/helpers/normalize-extent.js | 42 +- .../src/helpers/normalize-extent.spec.js | 84 +- .../src/helpers/normalize-input-data.js | 19 +- .../src/helpers/normalize-request-params.js | 11 +- .../helpers/normalize-request-params.spec.js | 20 +- .../helpers/normalize-spatial-reference.js | 60 +- .../normalize-spatial-reference.spec.js | 36 +- .../featureserver/src/helpers/renderers.js | 59 +- .../src/helpers/renderers.spec.js | 57 +- .../src/helpers/table-layer-metadata.js | 127 +- .../src/helpers/table-layer-metadata.spec.js | 47 +- .../src/helpers/validate-inputs.spec.js | 24 +- packages/featureserver/src/index.js | 2 +- packages/featureserver/src/layer-metadata.js | 4 +- .../featureserver/src/layer-metadata.spec.js | 28 +- packages/featureserver/src/layers-metadata.js | 9 +- .../featureserver/src/layers-metadata.spec.js | 42 +- packages/featureserver/src/log-manager.js | 8 +- .../featureserver/src/metadata-defaults.js | 4 +- .../src/metadata-defaults.spec.js | 9 +- .../src/query/filter-and-transform.js | 34 +- .../src/query/filter-and-transform.spec.js | 28 +- .../featureserver/src/query/index.spec.js | 339 +- .../src/query/log-provider-data-warnings.js | 39 +- .../query/log-provider-data-warnings.spec.js | 107 +- .../src/query/render-count-and-extent.js | 16 +- .../src/query/render-count-and-extent.spec.js | 108 +- .../src/query/render-features.spec.js | 24 +- .../query/render-precalculated-statistics.js | 28 +- .../render-precalculated-statistics.spec.js | 41 +- .../src/query/render-statistics.js | 16 +- .../src/query/render-statistics.spec.js | 114 +- .../validate-query-request-parameters.js | 23 +- .../validate-query-request-parameters.spec.js | 4 +- .../featureserver/src/queryRelatedRecords.js | 27 +- .../general-response-handler.js | 6 +- .../general-response-handler.spec.js | 5 +- .../src/response-handlers/helpers/index.js | 2 +- .../helpers/send-callback.js | 4 +- .../helpers/send-callback.spec.js | 12 +- .../send-pbf/FeatureCollection.proto.js | 6686 ++++++++++------- .../send-pbf/get-geometry-transform.js | 21 +- .../send-pbf/get-geometry-transform.spec.js | 25 +- .../helpers/send-pbf/index.spec.js | 42 +- .../send-pbf/transform-features-for-pbf.js | 31 +- .../transform-features-for-pbf.spec.js | 2 +- .../transform-to-pbf-geometry.spec.js | 73 +- .../helpers/send-pretty-json.js | 3 +- .../helpers/send-pretty-json.spec.js | 4 +- .../src/response-handlers/index.js | 2 +- .../query-response-handler.js | 18 +- .../query-response-handler.spec.js | 7 +- .../src/rest-info-route-handler.js | 18 +- packages/featureserver/src/route.js | 39 +- .../src/server-info-route-handler.js | 12 +- .../src/server-info-route-handler.spec.js | 35 +- .../test/integration/query.spec.js | 515 +- .../integration/queryRelatedRecords.spec.js | 10 +- .../test/integration/schemas/index.js | 86 +- packages/logger/src/index.spec.js | 4 +- packages/output-geoservices/src/index.js | 9 +- packages/output-geoservices/src/index.spec.js | 2 +- packages/winnow/benchmark/index.js | 14 +- ...er-and-validate-classification-features.js | 27 +- packages/winnow/src/errors.js | 6 +- .../filter-and-transform.js | 10 +- .../filter-and-transform.spec.js | 105 +- .../filters/contains.spec.js | 58 +- .../filters/envelope-intersects.js | 24 +- .../filters/envelope-intersects.spec.js | 180 +- .../filters/hashed-objectid-comparator.js | 10 +- .../hashed-objectid-comparator.spec.js | 39 +- .../src/filter-and-transform/filters/index.js | 2 +- .../filters/intersects.js | 6 +- .../filters/intersects.spec.js | 85 +- .../filters/within.spec.js | 58 +- .../helpers/create-integer-hash.js | 4 +- .../helpers/create-integer-hash.spec.js | 4 +- .../helpers/hash-function.js | 9 +- .../helpers/hash-function.spec.js | 30 +- .../src/filter-and-transform/helpers/index.js | 2 +- .../winnow/src/filter-and-transform/index.js | 2 +- .../prepare-filter-and-transform.js | 9 +- .../prepare-filter-and-transform.spec.js | 9 +- .../filter-and-transform/transforms/index.js | 2 +- .../transforms/project.js | 20 +- .../transforms/project.spec.js | 46 +- .../transforms/reduce-precision.js | 18 +- .../transforms/reduce-precision.spec.js | 10 +- .../select-fields-to-esri-attributes.js | 17 +- .../transforms/select-fields.js | 2 +- .../transforms/to-esri-attributes.js | 64 +- .../transforms/to-esri-geometry.js | 2 +- .../transforms/to-esri-geometry.spec.js | 5 +- .../transforms/to-geohash.js | 2 +- .../transforms/to-geohash.spec.js | 71 +- .../transforms/to-hash.js | 2 +- .../transforms/to-hash.spec.js | 6 +- .../winnow/src/helpers/project-coordinates.js | 18 +- .../src/helpers/project-coordinates.spec.js | 23 +- .../src/helpers/transform-coordinates.js | 8 +- .../src/helpers/transform-coordinates.spec.js | 71 +- packages/winnow/src/index.js | 2 +- packages/winnow/src/log-manager.js | 6 +- .../src/normalize-query-options/aggregates.js | 14 +- .../aggregates.spec.js | 44 +- .../classification.spec.js | 76 +- .../src/normalize-query-options/collection.js | 8 +- .../collection.spec.js | 27 +- .../normalize-query-options/date-fields.js | 17 +- .../date-fields.spec.js | 37 +- .../src/normalize-query-options/fields.js | 2 +- .../normalize-query-options/fields.spec.js | 33 +- .../geometry-filter-spatial-reference.js | 15 +- .../geometry-filter-spatial-reference.spec.js | 28 +- .../geometry-filter.js | 31 +- .../geometry-filter.spec.js | 122 +- .../src/normalize-query-options/group-by.js | 2 +- .../normalize-query-options/group-by.spec.js | 29 +- .../helpers/detect-esri-field-type.js | 2 +- .../helpers/detect-esri-field-types.spec.js | 10 +- .../helpers/get-collection-crs.js | 8 +- .../helpers/get-collection-crs.spec.js | 20 +- .../normalize-query-options/helpers/index.js | 2 +- .../helpers/normalize-array.js | 5 +- .../src/normalize-query-options/id-field.js | 15 +- .../normalize-query-options/id-field.spec.js | 64 +- .../src/normalize-query-options/index.js | 14 +- .../src/normalize-query-options/limit.spec.js | 24 +- .../object-ids.spec.js | 16 +- .../src/normalize-query-options/offset.js | 6 +- .../normalize-query-options/offset.spec.js | 16 +- .../src/normalize-query-options/order.js | 2 +- .../src/normalize-query-options/order.spec.js | 27 +- .../output-data-spatial-reference.js | 19 +- .../output-data-spatial-reference.spec.js | 58 +- .../source-data-spatial-reference.js | 17 +- .../source-data-spatial-reference.spec.js | 31 +- .../spatial-predicate.js | 4 +- .../spatial-predicate.spec.js | 40 +- .../spatial-reference.js | 56 +- .../spatial-reference.spec.js | 43 +- .../src/normalize-query-options/where.js | 19 +- .../src/normalize-query-options/where.spec.js | 27 +- .../winnow/src/query/classification-query.js | 11 +- .../src/query/classification-query.spec.js | 71 +- packages/winnow/src/query/index.js | 2 +- .../winnow/src/query/normalize-query-input.js | 17 +- .../src/query/normalize-query-input.spec.js | 36 +- packages/winnow/src/query/package-features.js | 15 +- .../winnow/src/query/package-features.spec.js | 16 +- packages/winnow/src/query/prepare-query.js | 8 +- .../winnow/src/query/prepare-query.spec.js | 47 +- packages/winnow/src/query/query.js | 24 +- packages/winnow/src/query/query.spec.js | 166 +- .../winnow/src/query/unique-value-query.js | 16 +- .../src/query/unique-value-query.spec.js | 202 +- .../sql-query-builder/create-sql-params.js | 31 +- .../create-sql-params.spec.js | 20 +- .../sql-query-builder/create-sql-string.js | 7 +- .../create-sql-string.spec.js | 89 +- .../winnow/src/sql-query-builder/group-by.js | 10 +- .../src/sql-query-builder/group-by.spec.js | 13 +- .../winnow/src/sql-query-builder/index.js | 2 +- .../src/sql-query-builder/is-different-crs.js | 2 +- .../is-different-crs.spec.js | 14 +- .../winnow/src/sql-query-builder/order-by.js | 29 +- .../src/sql-query-builder/order-by.spec.js | 53 +- .../select/aggregation-select.js | 12 +- .../select/fields-select-fragment.js | 8 +- .../select/fields-select-fragment.spec.js | 96 +- .../select/geometry-select-fragment.js | 14 +- .../select/geometry-select-fragment.spec.js | 61 +- .../src/sql-query-builder/select/index.js | 14 +- .../sql-query-builder/select/index.spec.js | 4 +- .../sql-query-builder/where-builder/index.js | 16 +- .../where-builder/index.spec.js | 24 +- .../where-builder/to-json-where.js | 21 +- .../where-builder/to-json-where.spec.js | 4 +- .../winnow/test/integration/aggregate.spec.js | 142 +- .../test/integration/classification.spec.js | 131 +- .../winnow/test/integration/fields.spec.js | 12 +- .../winnow/test/integration/filter.spec.js | 44 +- .../winnow/test/integration/limit.spec.js | 16 +- .../winnow/test/integration/order.spec.js | 20 +- .../winnow/test/integration/prepare.spec.js | 56 +- .../winnow/test/integration/project.spec.js | 189 +- .../winnow/test/integration/to-esri.spec.js | 83 +- packages/winnow/test/integration/wfs.spec.js | 4 +- ...lient-requests-provider-w-id-field.spec.js | 12 +- ...ient-requests-provider-w-objectids.spec.js | 12 +- ...equests-provider-w-string-id-field.spec.js | 12 +- ...rovider-wo-objectids-wo-fields-def.spec.js | 12 +- ...ent-requests-provider-wo-objectids.spec.js | 12 +- test/geoservice-error-handling.spec.js | 6 +- test/geoservice-pbf.spec.js | 2 +- test/helpers/output-pull-with-callback.js | 16 +- test/helpers/provider-async-no-callback.js | 2 +- test/helpers/provider-async-with-callback.js | 2 +- test/helpers/provider-callback.js | 2 +- 256 files changed, 9784 insertions(+), 7212 deletions(-) create mode 100644 .changeset/rare-items-bow.md rename .eslintrc.js => eslint.config.js (54%) diff --git a/.changeset/rare-items-bow.md b/.changeset/rare-items-bow.md new file mode 100644 index 000000000..d284b6c3b --- /dev/null +++ b/.changeset/rare-items-bow.md @@ -0,0 +1,5 @@ +--- +"@koopjs/featureserver": patch +--- + +- remove regex and replace with trim diff --git a/.prettierrc b/.prettierrc index 93a152cb5..73f3c7c38 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,6 @@ "singleQuote": true, "trailingComma": "all", "tabWidth": 2, - "useTabs": false + "useTabs": false, + "endOfLine": "lf" } \ No newline at end of file diff --git a/.eslintrc.js b/eslint.config.js similarity index 54% rename from .eslintrc.js rename to eslint.config.js index 6d9ac42f0..30fce0988 100644 --- a/.eslintrc.js +++ b/eslint.config.js @@ -1,14 +1,15 @@ +const noOnlyTests = require('eslint-plugin-no-only-tests'); +const prettier = require('eslint-plugin-prettier'); + module.exports = { - env: { + languageOptions: { + globals: { commonjs: true, es6: true, mocha: true, jest: true, jasmine: true, node: true, - }, - extends: 'eslint:recommended', - globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly', process: 'readonly', @@ -18,13 +19,17 @@ module.exports = { parserOptions: { ecmaVersion: 2022, }, +}, + rules: { 'no-unused-vars': ['error', { ignoreRestSiblings: true }], - indent: ['error', 2, { SwitchCase: 1 }], - 'linebreak-style': ['error', 'unix'], - quotes: ['error', 'single'], - semi: ['error', 'always'], + 'semi': ['error', 'always'], + 'prettier/prettier': ['error', {endOfLine: 'auto'}], 'no-only-tests/no-only-tests': 'error', + //'linebreak-style': ['error', 'unix'], + }, + plugins: { + 'no-only-tests': noOnlyTests, + 'prettier': prettier }, - plugins: ['no-only-tests'], }; diff --git a/package-lock.json b/package-lock.json index 85d90f620..3392b356b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "packages/core" ], "devDependencies": { - "@babel/eslint-parser": "^7.24.1", "@changesets/changelog-git": "^0.2.0", "@changesets/cli": "^2.27.1", "@commitlint/config-conventional": "^19.1.0", @@ -31,8 +30,10 @@ "cross-env": "^7.0.3", "cz-conventional-changelog": "^3.3.0", "cz-git": "^1.9.1", - "eslint": "^8.57.0", + "eslint": "^9.0.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "jest": "^29.7.0", "jest-coverage-badges-ng": "^1.0.1", @@ -128,24 +129,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/eslint-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.1.tgz", - "integrity": "sha512-d5guuzMlPeDfZIbpQ8+g1NaCNuAGBBGNECh0HVqz1sjOeVLh2CEaifuOysCH18URW6R7pqXINvf5PaR/dC6jLQ==", - "dev": true, - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0" - } - }, "node_modules/@babel/generator": { "version": "7.20.1", "dev": true, @@ -2312,15 +2295,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.0.2.tgz", + "integrity": "sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -2328,7 +2311,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2351,15 +2334,12 @@ } }, "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2371,25 +2351,13 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.0.0.tgz", + "integrity": "sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@esri/proj-codes": { @@ -2414,12 +2382,12 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.12.3.tgz", + "integrity": "sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -2440,9 +2408,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "node_modules/@hutson/parse-repository-url": { @@ -3920,14 +3888,6 @@ "node": ">= 4.0.0" } }, - "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-scope": "5.1.1" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -4709,6 +4669,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -5407,12 +5379,6 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -5487,9 +5453,10 @@ } }, "node_modules/acorn": { - "version": "8.9.0", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -8027,17 +7994,6 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/dot-prop": { "version": "5.3.0", "dev": true, @@ -8402,41 +8358,37 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.0.0.tgz", + "integrity": "sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/eslintrc": "^3.0.2", + "@eslint/js": "9.0.0", + "@humanwhocodes/config-array": "^0.12.3", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^8.0.1", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -8450,12 +8402,24 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-plugin-no-only-tests": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz", @@ -8465,24 +8429,34 @@ "node": ">=5.0.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", + "node_modules/eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10" + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } } }, "node_modules/eslint/node_modules/ajv": { @@ -8557,26 +8531,28 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", + "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.4.3", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, - "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -8584,26 +8560,13 @@ }, "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.21.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint/node_modules/has-flag": { "version": "4.0.0", "dev": true, @@ -8628,41 +8591,30 @@ "node": ">=8" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", + "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", "dev": true, "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.11.3", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -8726,18 +8678,11 @@ "bbox2extent": "^1.0.1" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, "node_modules/esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -9074,6 +9019,12 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.2.12", "dev": true, @@ -9153,14 +9104,15 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, - "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/filelist": { @@ -9314,21 +9266,23 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.7", - "dev": true, - "license": "ISC" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true }, "node_modules/fn.name": { "version": "1.1.0", @@ -13143,6 +13097,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -13294,6 +13254,15 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -18169,6 +18138,18 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -20573,6 +20554,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tap-min": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tap-min/-/tap-min-3.0.0.tgz", @@ -20971,9 +20968,10 @@ } }, "node_modules/tslib": { - "version": "2.4.1", - "dev": true, - "license": "0BSD" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true }, "node_modules/tty-table": { "version": "4.1.6", @@ -22247,17 +22245,6 @@ "semver": "^6.3.0" } }, - "@babel/eslint-parser": { - "version": "7.24.1", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.24.1.tgz", - "integrity": "sha512-d5guuzMlPeDfZIbpQ8+g1NaCNuAGBBGNECh0HVqz1sjOeVLh2CEaifuOysCH18URW6R7pqXINvf5PaR/dC6jLQ==", - "dev": true, - "requires": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - } - }, "@babel/generator": { "version": "7.20.1", "dev": true, @@ -23814,15 +23801,15 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.0.2.tgz", + "integrity": "sha512-wV19ZEGEMAC1eHgrS7UQPqsdEiCIbTKTasEfcXAigzoXICcqZSjBZEHlZwNVvKg6UBCjSlos84XiLqsRJnIcIg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -23843,32 +23830,23 @@ } }, "globals": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", - "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true } } }, "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.0.0.tgz", + "integrity": "sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==", "dev": true }, "@esri/proj-codes": { @@ -23890,12 +23868,12 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.12.3.tgz", + "integrity": "sha512-jsNnTBlMWuTpDkeE3on7+dWJi0D6fdDfeANj/w7MpS8ztROCoLvIO2nG0CcFj+E4k8j4QrSTh4Oryi3i2G669g==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" } @@ -23905,9 +23883,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "@hutson/parse-repository-url": { @@ -25106,13 +25084,6 @@ } } }, - "@nicolo-ribaudo/eslint-scope-5-internals": { - "version": "5.1.1-v1", - "dev": true, - "requires": { - "eslint-scope": "5.1.1" - } - }, "@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -25654,6 +25625,12 @@ "dev": true, "optional": true }, + "@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -26243,12 +26220,6 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, "@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -26309,7 +26280,9 @@ } }, "acorn": { - "version": "8.9.0", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true }, "acorn-jsx": { @@ -28021,13 +27994,6 @@ "path-type": "^4.0.0" } }, - "doctrine": { - "version": "3.0.0", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, "dot-prop": { "version": "5.3.0", "dev": true, @@ -28288,41 +28254,37 @@ "dev": true }, "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.0.0.tgz", + "integrity": "sha512-IMryZ5SudxzQvuod6rUdIUz29qFItWx281VhtFVc2Psy/ZhlCeD/5DT6lBIJ4H3G+iamGJoTln1v+QSuPw0p7Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint/eslintrc": "^3.0.2", + "@eslint/js": "9.0.0", + "@humanwhocodes/config-array": "^0.12.3", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", + "eslint-scope": "^8.0.1", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.0.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", @@ -28374,7 +28336,9 @@ "dev": true }, "eslint-scope": { - "version": "7.2.2", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz", + "integrity": "sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -28382,20 +28346,17 @@ } }, "eslint-visitor-keys": { - "version": "3.4.3", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true }, "estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true }, - "globals": { - "version": "13.21.0", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, "has-flag": { "version": "4.0.0", "dev": true @@ -28410,46 +28371,47 @@ "requires": { "has-flag": "^4.0.0" } - }, - "type-fest": { - "version": "0.20.2", - "dev": true } } }, + "eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "requires": {} + }, "eslint-plugin-no-only-tests": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz", "integrity": "sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==", "dev": true }, - "eslint-scope": { - "version": "5.1.1", + "eslint-plugin-prettier": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", + "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", "dev": true, "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.8.6" } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "dev": true - }, "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", + "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", "dev": true, "requires": { - "acorn": "^8.9.0", + "acorn": "^8.11.3", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "dependencies": { "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true } } @@ -28491,12 +28453,10 @@ "bbox2extent": "^1.0.1" } }, - "estraverse": { - "version": "4.3.0", - "dev": true - }, "esutils": { "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "etag": { @@ -28766,6 +28726,12 @@ "version": "3.1.3", "dev": true }, + "fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "fast-glob": { "version": "3.2.12", "dev": true, @@ -28829,10 +28795,12 @@ } }, "file-entry-cache": { - "version": "6.0.1", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "requires": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" } }, "filelist": { @@ -28945,15 +28913,19 @@ "dev": true }, "flat-cache": { - "version": "3.0.4", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" } }, "flatted": { - "version": "3.2.7", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "fn.name": { @@ -31557,6 +31529,12 @@ "version": "2.5.2", "dev": true }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -31668,6 +31646,15 @@ "safe-buffer": "^5.0.1" } }, + "keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, "kind-of": { "version": "6.0.3", "dev": true @@ -35043,6 +35030,15 @@ "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", "dev": true }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", @@ -36739,6 +36735,16 @@ "version": "1.0.0", "dev": true }, + "synckit": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", + "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", + "dev": true, + "requires": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + } + }, "tap-min": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/tap-min/-/tap-min-3.0.0.tgz", @@ -37011,7 +37017,9 @@ } }, "tslib": { - "version": "2.4.1", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, "tty-table": { diff --git a/package.json b/package.json index 170587b50..05f57079c 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "packages/core" ], "devDependencies": { - "@babel/eslint-parser": "^7.24.1", "@changesets/changelog-git": "^0.2.0", "@changesets/cli": "^2.27.1", "@commitlint/config-conventional": "^19.1.0", @@ -57,8 +56,10 @@ "cross-env": "^7.0.3", "cz-conventional-changelog": "^3.3.0", "cz-git": "^1.9.1", - "eslint": "^8.57.0", + "eslint": "^9.0.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-no-only-tests": "^3.1.0", + "eslint-plugin-prettier": "^5.1.3", "husky": "^9.0.11", "jest": "^29.7.0", "jest-coverage-badges-ng": "^1.0.1", diff --git a/packages/cache-memory/src/index.spec.js b/packages/cache-memory/src/index.spec.js index b4a5475c2..251a9f569 100644 --- a/packages/cache-memory/src/index.spec.js +++ b/packages/cache-memory/src/index.spec.js @@ -1,7 +1,7 @@ const test = require('tape'); const { v4: uuidv4 } = require('uuid'); const { promisify } = require('util'); -const delay = promisify(setTimeout); +const delay = promisify(setTimeout); const Cache = require('../src'); const cache = new Cache(); @@ -45,7 +45,7 @@ test('retrieve partial entry with pick option', async (t) => { const geojson = getFeatureCollection(); const key = uuidv4(); await cache.insert(key, geojson, { ttl: 600 }); - const cached = await cache.retrieve(key, { pick: ['features'] }); + const cached = await cache.retrieve(key, { pick: ['features'] }); t.deepEqual(Object.keys(cached), ['features'], 'retrieved only features'); t.end(); }); @@ -54,7 +54,7 @@ test('retrieve partial entry with omit option', async (t) => { const geojson = getFeatureCollection(); const key = uuidv4(); await cache.insert(key, geojson, { ttl: 600 }); - const cached = await cache.retrieve(key, { omit: ['features'] }); + const cached = await cache.retrieve(key, { omit: ['features'] }); t.deepEqual( Object.keys(cached), ['type', 'crs', 'metadata'], diff --git a/packages/core/src/data-provider/extend-controller.js b/packages/core/src/data-provider/extend-controller.js index cf6d7aa0b..31f62c144 100644 --- a/packages/core/src/data-provider/extend-controller.js +++ b/packages/core/src/data-provider/extend-controller.js @@ -3,18 +3,25 @@ class DefaultController {} /** * We extend all controllers to ensure the following properties exist: this.model, this.routes, this.namespace */ -module.exports = function extendController (model, BaseController = DefaultController, options) { +module.exports = function extendController( + model, + BaseController = DefaultController, + options, +) { class Controller extends BaseController { - constructor (model, options) { + constructor(model, options) { super(model, options); this.model = model; } } const controller = new Controller(model, options); - const controllerEnumerables = Object.keys(BaseController).reduce((acc, member) => { - acc[member] = BaseController[member]; - return acc; - }, {}); + const controllerEnumerables = Object.keys(BaseController).reduce( + (acc, member) => { + acc[member] = BaseController[member]; + return acc; + }, + {}, + ); Object.assign(controller, controllerEnumerables); controller.routes = controller.routes || []; diff --git a/packages/core/src/data-provider/extend-controller.spec.js b/packages/core/src/data-provider/extend-controller.spec.js index c37eed2cb..fe90fddcd 100644 --- a/packages/core/src/data-provider/extend-controller.spec.js +++ b/packages/core/src/data-provider/extend-controller.spec.js @@ -1,10 +1,10 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const extendController = require('./extend-controller'); describe('Tests for create-controller', function () { it('should extend a controller authored with function syntax', () => { - const OutputController = function OutputController () { + const OutputController = function OutputController() { this.foo = 'bar'; }; OutputController.routes = ['route-test']; @@ -18,7 +18,7 @@ describe('Tests for create-controller', function () { it('should extend a controller authored with class syntax', () => { class OutputController { - constructor () { + constructor() { this.foo = 'bar'; } } @@ -42,6 +42,9 @@ describe('Tests for create-controller', function () { it('should use a default namespace when unnamed constructor functions are used', () => { const mockModel = 'model-test'; const extendedController = extendController(mockModel, function () {}); - extendedController.should.have.property('namespace', 'UndefinedControllerNamespace'); + extendedController.should.have.property( + 'namespace', + 'UndefinedControllerNamespace', + ); }); }); diff --git a/packages/core/src/data-provider/extend-model.js b/packages/core/src/data-provider/extend-model.js index 20ce4c5eb..b4bc47959 100644 --- a/packages/core/src/data-provider/extend-model.js +++ b/packages/core/src/data-provider/extend-model.js @@ -2,11 +2,16 @@ const { promisify } = require('util'); const hasher = require('@sindresorhus/fnv1a'); const beforeNoop = async () => {}; -const afterNoop = async (req, data) => { return data; }; +const afterNoop = async (req, data) => { + return data; +}; const cacheRetrieveNoop = async () => {}; const cacheInsertNoop = async () => {}; -module.exports = function extendModel ({ ProviderModel, namespace, logger, cache, authModule }, options = {}) { +module.exports = function extendModel( + { ProviderModel, namespace, logger, cache, authModule }, + options = {}, +) { class Model extends ProviderModel { #cacheTtl; #before; @@ -17,7 +22,7 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache #getLayer; #getCatalog; - constructor ({ logger, cache }, options) { + constructor({ logger, cache }, options) { super({ logger, log: logger }, options); // Provider constructor's may assign values to this.cache @@ -26,20 +31,37 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache this.#cacheTtl = options.cacheTtl; this.namespace = namespace; this.logger = logger; - this.#before = this.#normalizeAndBindMethod(options.before || beforeNoop, 2); + this.#before = this.#normalizeAndBindMethod( + options.before || beforeNoop, + 2, + ); this.#after = this.#normalizeAndBindMethod(options.after || afterNoop, 3); - this.#cacheRetrieve = this.#normalizeAndBindMethod(modelCache?.retrieve || cacheRetrieveNoop, 3, modelCache); - this.#cacheInsert = this.#normalizeAndBindMethod(modelCache?.insert || cacheInsertNoop, 4, modelCache); + this.#cacheRetrieve = this.#normalizeAndBindMethod( + modelCache?.retrieve || cacheRetrieveNoop, + 3, + modelCache, + ); + this.#cacheInsert = this.#normalizeAndBindMethod( + modelCache?.insert || cacheInsertNoop, + 4, + modelCache, + ); this.#getProviderData = this.#normalizeAndBindMethod(this.getData, 2); - this.#getLayer = this.getLayer ? this.#normalizeAndBindMethod(this.getLayer, 2) : undefined; - this.#getCatalog = this.getCatalog ? this.#normalizeAndBindMethod(this.getCatalog, 2) : undefined; + this.#getLayer = this.getLayer + ? this.#normalizeAndBindMethod(this.getLayer, 2) + : undefined; + this.#getCatalog = this.getCatalog + ? this.#normalizeAndBindMethod(this.getCatalog, 2) + : undefined; } - #normalizeAndBindMethod (func, callbackArgumentIndex, context = this) { - return func?.length === callbackArgumentIndex ? promisify(func).bind(context) : func.bind(context); + #normalizeAndBindMethod(func, callbackArgumentIndex, context = this) { + return func?.length === callbackArgumentIndex + ? promisify(func).bind(context) + : func.bind(context); } - async pull (req, callback) { + async pull(req, callback) { const { error } = await this.#authorizeRequest(req); if (error) { return this.#handleReturn(callback, error); @@ -56,7 +78,7 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache } catch (err) { this.logger.debug(err); } - + try { await this.#before(req); const providerGeojson = await this.#getProviderData(req); @@ -84,17 +106,21 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache return returnValue; } - // TODO: the pullLayer() and the pullCatalog() are very similar to the pull() // function. We may consider to merging them in the future. - async pullLayer (req, callback) { + async pullLayer(req, callback) { const { error } = await this.#authorizeRequest(req); if (error) { return this.#handleReturn(callback, error); } if (!this.#getLayer) { - return this.#handleReturn(callback, new Error(`getLayer() method is not implemented in the ${this.namespace} provider.`)); + return this.#handleReturn( + callback, + new Error( + `getLayer() method is not implemented in the ${this.namespace} provider.`, + ), + ); } const key = `${this.#createCacheKey(req)}::layer`; @@ -121,14 +147,19 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache } } - async pullCatalog (req, callback) { + async pullCatalog(req, callback) { const { error } = await this.#authorizeRequest(req); if (error) { return this.#handleReturn(callback, error); } if (!this.#getCatalog) { - return this.#handleReturn(callback, new Error(`getCatalog() method is not implemented in the ${this.namespace} provider.`)); + return this.#handleReturn( + callback, + new Error( + `getCatalog() method is not implemented in the ${this.namespace} provider.`, + ), + ); } const key = `${this.#createCacheKey(req)}::catalog`; @@ -155,23 +186,25 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache } } - async pullStream (req) { + async pullStream(req) { const { error } = await this.#authorizeRequest(req); - + if (error) { throw error; } - + if (this.getStream) { await this.#before(req); const providerStream = await this.getStream(req); return providerStream; } else { - throw new Error('getStream() function is not implemented in the provider.'); + throw new Error( + 'getStream() function is not implemented in the provider.', + ); } } - #createCacheKey (req) { + #createCacheKey(req) { const providerKeyGenerator = this.createCacheKey || this.createKey; if (providerKeyGenerator) { return providerKeyGenerator(req); @@ -179,7 +212,7 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache return hasher(req.url).toString(); } - async #authorizeRequest (req) { + async #authorizeRequest(req) { try { await this.authorize(req); } catch (error) { @@ -193,22 +226,33 @@ module.exports = function extendModel ({ ProviderModel, namespace, logger, cache // If provider has auth methods use them, then use auth-module methods, otherwise dummy methods if (typeof ProviderModel.prototype.authorize !== 'function') { - Model.prototype.authorize = typeof authModule?.authorize === 'function' ? authModule.authorize : async () => {}; + Model.prototype.authorize = + typeof authModule?.authorize === 'function' + ? authModule.authorize + : async () => {}; } if (typeof ProviderModel.prototype.authenticate !== 'function') { - Model.prototype.authenticate = typeof authModule?.authenticate === 'function' ? authModule?.authenticate : async () => { return {}; }; + Model.prototype.authenticate = + typeof authModule?.authenticate === 'function' + ? authModule?.authenticate + : async () => { + return {}; + }; } - if(typeof authModule?.authenticationSpecification === 'function') { - logger.warn('Use of "authenticationSpecification" is deprecated. It will be removed in a future release.'); - Model.prototype.authenticationSpecification = authModule?.authenticationSpecification; + if (typeof authModule?.authenticationSpecification === 'function') { + logger.warn( + 'Use of "authenticationSpecification" is deprecated. It will be removed in a future release.', + ); + Model.prototype.authenticationSpecification = + authModule?.authenticationSpecification; } return new Model({ logger, cache }, options); }; -function shouldUseCache (cacheEntry) { +function shouldUseCache(cacheEntry) { // older cache plugins stored expiry time explicitly; all caches should move to returning empty if expired if (!cacheEntry) { return false; @@ -218,6 +262,6 @@ function shouldUseCache (cacheEntry) { if (!expires) { return true; } - + return Date.now() < expires; } diff --git a/packages/core/src/data-provider/extend-model.spec.js b/packages/core/src/data-provider/extend-model.spec.js index 29a479329..4800ce752 100644 --- a/packages/core/src/data-provider/extend-model.spec.js +++ b/packages/core/src/data-provider/extend-model.spec.js @@ -110,20 +110,20 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return { metadata: {} }; }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; - + const model = extendModel({ ProviderModel: Model, logger: mockLogger, cache: mockCache, }); - + const data = await model.pull({ url: 'domain/test-provider', params: {}, @@ -134,7 +134,7 @@ describe('Tests for extend-model', function () { getDataSpy.called.should.equal(true); mockCache.insert.notCalled.should.equal(true); }); - + it('should not find in cache, should add to cache due to data ttl', async () => { const mockCache = { retrieve: sinon.spy((key, query, callback) => { @@ -142,7 +142,7 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return { metadata: {}, ttl: 5 }; }); @@ -164,7 +164,7 @@ describe('Tests for extend-model', function () { getDataSpy.calledOnce.should.equal(true); mockCache.insert.calledOnce.should.equal(true); }); - + it('should not find in cache, should add to cache due to provider ttl', async () => { const mockCache = { retrieve: sinon.spy((key, query, callback) => { @@ -172,11 +172,11 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return { metadata: {} }; }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; const model = extendModel( @@ -196,7 +196,7 @@ describe('Tests for extend-model', function () { getDataSpy.calledOnce.should.equal(true); mockCache.insert.calledOnce.should.equal(true); }); - + it('should pull from cache', async () => { const mockCache = { retrieve: sinon.spy((key, query, callback) => { @@ -204,11 +204,11 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return; }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; const model = extendModel({ @@ -229,7 +229,7 @@ describe('Tests for extend-model', function () { getDataSpy.notCalled.should.equal(true); mockCache.insert.notCalled.should.equal(true); }); - + it('should pull from cache and use deprecated _cache info', async () => { const now = Date.now(); const mockCache = { @@ -244,11 +244,11 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return; }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; const model = extendModel({ @@ -256,7 +256,7 @@ describe('Tests for extend-model', function () { logger: mockLogger, cache: mockCache, }); - + const data = await model.pull({ url: 'domain/test-provider', params: {}, @@ -273,7 +273,7 @@ describe('Tests for extend-model', function () { getDataSpy.notCalled.should.equal(true); mockCache.insert.notCalled.should.equal(true); }); - + it('should pull from cache and use deprecated metadata info check', async () => { const now = Date.now(); const mockCache = { @@ -288,11 +288,11 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { return; }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; const model = extendModel({ @@ -300,7 +300,7 @@ describe('Tests for extend-model', function () { logger: mockLogger, cache: mockCache, }); - + const data = await model.pull({ url: 'domain/test-provider', params: {}, @@ -317,7 +317,7 @@ describe('Tests for extend-model', function () { getDataSpy.notCalled.should.equal(true); mockCache.insert.notCalled.should.equal(true); }); - + it('should pass authorization error in callback', async () => { const mockCache = { retrieve: sinon.spy((key, query, callback) => { @@ -325,12 +325,12 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + class Model extends MockModel {} Model.prototype.authorize = async () => { throw new Error('unauthorized'); }; - + const model = extendModel({ ProviderModel: Model, logger: mockLogger, @@ -338,13 +338,17 @@ describe('Tests for extend-model', function () { }); try { - await model.pull({ url: 'domain/test-provider', params: {}, query: {} }); + await model.pull({ + url: 'domain/test-provider', + params: {}, + query: {}, + }); should.fail(); } catch (err) { err.message.should.equal('unauthorized'); } }); - + it('should send error in callback', async () => { const mockCache = { retrieve: sinon.spy((key, query, callback) => { @@ -352,11 +356,11 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(async function () { throw new Error('err in getData'); }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; const model = extendModel({ @@ -366,7 +370,11 @@ describe('Tests for extend-model', function () { }); try { - await model.pull({ url: 'domain/test-provider', params: {}, query: {} }); + await model.pull({ + url: 'domain/test-provider', + params: {}, + query: {}, + }); should.fail(); } catch (err) { err.message.should.equal('err in getData'); @@ -382,22 +390,22 @@ describe('Tests for extend-model', function () { }), insert: sinon.spy(() => {}), }; - + const getDataSpy = sinon.spy(function (req, callback) { callback(null, { metadata: {} }); }); - + class Model extends MockModel {} Model.prototype.getData = getDataSpy; - + const model = extendModel({ ProviderModel: Model, logger: mockLogger, cache: mockCache, }); - + const pullData = promisify(model.pull).bind(model); - + const data = await pullData({ url: 'domain/test-provider', params: {}, @@ -461,8 +469,7 @@ describe('Tests for extend-model', function () { }, authenticationSpecification: () => { return 'from auth-module'; - } - + }, }, }); const authenticateResult = await model.authenticate(); @@ -475,11 +482,11 @@ describe('Tests for extend-model', function () { it('should use provider auth methods if defined', async () => { class Model extends MockModel {} - Model.prototype.authenticate = async() => { + Model.prototype.authenticate = async () => { return 'from provider'; }; - Model.prototype.authorize = async() => { + Model.prototype.authorize = async () => { return 'from provider'; }; @@ -494,7 +501,7 @@ describe('Tests for extend-model', function () { }, authorize: () => { return 'from auth-module'; - } + }, }, }); const authenticateResult = await model.authenticate(); @@ -515,7 +522,6 @@ describe('Tests for extend-model', function () { const authorizeResult = await model.authorize(); should(authorizeResult).deepEqual(undefined); }); - }); describe('transformation functions', function () { @@ -1065,7 +1071,11 @@ describe('Tests for extend-model', function () { const pullCatalog = promisify(model.pullCatalog).bind(model); try { - await pullCatalog({ url: 'domain/test-provider', params: {}, query: {} }); + await pullCatalog({ + url: 'domain/test-provider', + params: {}, + query: {}, + }); should.fail(); } catch (err) { err.message.should.equal('unauthorized'); diff --git a/packages/core/src/data-provider/helpers/compose-route-path.js b/packages/core/src/data-provider/helpers/compose-route-path.js index 8491658f8..fc594d446 100644 --- a/packages/core/src/data-provider/helpers/compose-route-path.js +++ b/packages/core/src/data-provider/helpers/compose-route-path.js @@ -17,7 +17,10 @@ function composeRoutePath(params) { return routeJoiner(routePrefix, path); } - const providerParamsFragment = getProviderParamsFragment(hosts, disableIdParam); + const providerParamsFragment = getProviderParamsFragment( + hosts, + disableIdParam, + ); if (path.includes('$namespace') || path.includes('$providerParams')) { const paramsPath = path @@ -26,7 +29,12 @@ function composeRoutePath(params) { return routeJoiner(routePrefix, paramsPath); } - return routeJoiner(routePrefix, providerNamespace, providerParamsFragment, path); + return routeJoiner( + routePrefix, + providerNamespace, + providerParamsFragment, + path, + ); } function getProviderParamsFragment(hosts, disableIdParam) { diff --git a/packages/core/src/data-provider/helpers/compose-route-path.spec.js b/packages/core/src/data-provider/helpers/compose-route-path.spec.js index cdf15e46a..a84d125cb 100644 --- a/packages/core/src/data-provider/helpers/compose-route-path.spec.js +++ b/packages/core/src/data-provider/helpers/compose-route-path.spec.js @@ -1,41 +1,67 @@ const { composeRoutePath } = require('./'); -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line describe('Tests for composeRoutePath', function () { it('create route with :host and :id parameter', function () { - const params = { hosts: true, providerNamespace: 'test', path: 'FeatureServer/:layer/:method' }; + const params = { + hosts: true, + providerNamespace: 'test', + path: 'FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/test/:host/:id/FeatureServer/:layer/:method'); }); it('create route with :host parameter and without :id parameter', function () { - const params = { hosts: true, disableIdParam: true, providerNamespace: 'test', path: 'FeatureServer/:layer/:method' }; + const params = { + hosts: true, + disableIdParam: true, + providerNamespace: 'test', + path: 'FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/test/:host/FeatureServer/:layer/:method'); }); it('create route without :host parameter', function () { - const params = { providerNamespace: 'test', path: 'FeatureServer/:layer/:method' }; + const params = { + providerNamespace: 'test', + path: 'FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/test/:id/FeatureServer/:layer/:method'); }); it('create route without :host and :id parameter', function () { - const params = { providerNamespace: 'test', disableIdParam: true, path: 'FeatureServer/:layer/:method' }; + const params = { + providerNamespace: 'test', + disableIdParam: true, + path: 'FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/test/FeatureServer/:layer/:method'); }); it('create route with templated $namespace$ substring', function () { - const params = { providerNamespace: 'test', disableIdParam: true, path: '$namespace/rest/services/FeatureServer/:layer/:method' }; + const params = { + providerNamespace: 'test', + disableIdParam: true, + path: '$namespace/rest/services/FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/test/rest/services/FeatureServer/:layer/:method'); }); it('create route with templated $namespace$ and $providerParams$ substrings', function () { - const params = { providerNamespace: 'test', hosts: true, path: '$namespace/rest/services/$providerParams/FeatureServer/:layer/:method' }; + const params = { + providerNamespace: 'test', + hosts: true, + path: '$namespace/rest/services/$providerParams/FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); - fullRoute.should.equal('/test/rest/services/:host/:id/FeatureServer/:layer/:method'); + fullRoute.should.equal( + '/test/rest/services/:host/:id/FeatureServer/:layer/:method', + ); }); it('create route without path construction', function () { @@ -45,7 +71,11 @@ describe('Tests for composeRoutePath', function () { }); it('create route with prefix, :host, :id parameters', function () { - const params = { providerNamespace: 'test', routePrefix: 'api/v1', path: 'FeatureServer/:layer/:method' }; + const params = { + providerNamespace: 'test', + routePrefix: 'api/v1', + path: 'FeatureServer/:layer/:method', + }; const fullRoute = composeRoutePath(params); fullRoute.should.equal('/api/v1/test/:id/FeatureServer/:layer/:method'); }); diff --git a/packages/core/src/data-provider/helpers/index.js b/packages/core/src/data-provider/helpers/index.js index d55323ae0..414d1142c 100644 --- a/packages/core/src/data-provider/helpers/index.js +++ b/packages/core/src/data-provider/helpers/index.js @@ -1,5 +1,4 @@ - module.exports = { composeRoutePath: require('./compose-route-path'), - routeJoiner: require('./route-joiner') + routeJoiner: require('./route-joiner'), }; diff --git a/packages/core/src/data-provider/helpers/route-joiner.js b/packages/core/src/data-provider/helpers/route-joiner.js index e89b6e63e..d7097c865 100644 --- a/packages/core/src/data-provider/helpers/route-joiner.js +++ b/packages/core/src/data-provider/helpers/route-joiner.js @@ -1,18 +1,17 @@ const _ = require('lodash'); -module.exports = function join () { +module.exports = function join() { const path = _.chain(arguments) .values() - .filter(fragment => { + .filter((fragment) => { return !_.isEmpty(fragment) || fragment === '/'; - }).map(fragment => { - return fragment - .split('/') - .filter(fragment => fragment !== ''); + }) + .map((fragment) => { + return fragment.split('/').filter((fragment) => fragment !== ''); }) .flatten() .join('/') .value(); - + return `/${path}`; }; diff --git a/packages/core/src/data-provider/helpers/route-joiner.spec.js b/packages/core/src/data-provider/helpers/route-joiner.spec.js index d6e7667f5..c1e8030f6 100644 --- a/packages/core/src/data-provider/helpers/route-joiner.spec.js +++ b/packages/core/src/data-provider/helpers/route-joiner.spec.js @@ -1,5 +1,5 @@ const { routeJoiner } = require('./'); -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line describe('Tests for routeJoiner', function () { it('create route with simple fragments', function () { diff --git a/packages/core/src/data-provider/index.js b/packages/core/src/data-provider/index.js index 3084ea346..3461eb368 100644 --- a/packages/core/src/data-provider/index.js +++ b/packages/core/src/data-provider/index.js @@ -46,30 +46,31 @@ module.exports = class DataProvider { ..._.pick(pluginDefinition, 'hosts', 'disableIdParam'), }; - this.version = pluginDefinition.version || pluginDefinition?.status?.version || 'unknown'; - this.#urlSafeNamespace = this.namespace - .replace(/\s/g, '-') - .toLowerCase(); + this.#urlSafeNamespace = this.namespace.replace(/\s/g, '-').toLowerCase(); const model = extendModel( { ProviderModel: pluginDefinition.Model, namespace: this.namespace, - logger, cache, authModule, + logger, + cache, + authModule, }, options, ); this.#definedProviderRoutes = pluginDefinition.routes || []; - this.#outputPluginControllers = outputPlugins.map(({ outputClass, options }) => { - return extendRouteController(model, outputClass, options); - }); + this.#outputPluginControllers = outputPlugins.map( + ({ outputClass, options }) => { + return extendRouteController(model, outputClass, options); + }, + ); this.#providerController = extendRouteController( model, @@ -93,30 +94,32 @@ module.exports = class DataProvider { } #createOutputRoutes() { - this.outputPluginRoutes = this.#outputPluginControllers.map((controller) => { - const routes = controller.routes.map((route) => { - const { handler, path, methods } = route; - - const compositeRoute = new ProviderRoute({ - controller, - handler, - path, - methods, - providerNamespace: this.#urlSafeNamespace, - outputNamespace: controller.namespace, - hosts: this.#options.hosts, - disableIdParam: this.#options.disableIdParam, - routePrefix: this.#options.routePrefix, - absolutePath: this.#options.absolutePath, + this.outputPluginRoutes = this.#outputPluginControllers.map( + (controller) => { + const routes = controller.routes.map((route) => { + const { handler, path, methods } = route; + + const compositeRoute = new ProviderRoute({ + controller, + handler, + path, + methods, + providerNamespace: this.#urlSafeNamespace, + outputNamespace: controller.namespace, + hosts: this.#options.hosts, + disableIdParam: this.#options.disableIdParam, + routePrefix: this.#options.routePrefix, + absolutePath: this.#options.absolutePath, + }); + return compositeRoute; }); - return compositeRoute; - }); - return { - namespace: controller.namespace, - routes - }; - }); + return { + namespace: controller.namespace, + routes, + }; + }, + ); } #createProviderRoutes() { @@ -124,35 +127,35 @@ module.exports = class DataProvider { this.#logger.info(`[${this.namespace}] defined routes:`); } - this.providerRoutes = this.#definedProviderRoutes.map( - (route) => { - const { handler, path, methods } = route; - const registeredRoute = new ProviderRoute({ - controller: this.#providerController, - handler, - path, - methods, - providerNamespace: this.#urlSafeNamespace, - routePrefix: this.#options.routePrefix, - absolutePath: true - }); - this.#logger.info(`ROUTE | [${methods.join(', ').toUpperCase()}] | ${registeredRoute.path}`); - return registeredRoute; - }, - ); + this.providerRoutes = this.#definedProviderRoutes.map((route) => { + const { handler, path, methods } = route; + const registeredRoute = new ProviderRoute({ + controller: this.#providerController, + handler, + path, + methods, + providerNamespace: this.#urlSafeNamespace, + routePrefix: this.#options.routePrefix, + absolutePath: true, + }); + this.#logger.info( + `ROUTE | [${methods.join(', ').toUpperCase()}] | ${registeredRoute.path}`, + ); + return registeredRoute; + }); } - #addOutputRoutes (server) { - this.outputPluginRoutes.forEach((output => { + #addOutputRoutes(server) { + this.outputPluginRoutes.forEach((output) => { const { namespace: outputNamespace, routes } = output; this.#logger.info( `"${outputNamespace}" routes for the "${this.namespace}" provider:`, ); this.#addRouteCollection(server, routes); - })); + }); } - #addProviderRoutes (server) { + #addProviderRoutes(server) { if (this.providerRoutes.length > 0) { this.#logger.info(`[${this.namespace}] defined routes:`); } @@ -160,10 +163,10 @@ module.exports = class DataProvider { this.#addRouteCollection(server, this.providerRoutes); } - #addRouteCollection (server, routes) { - return routes.forEach(route =>{ + #addRouteCollection(server, routes) { + return routes.forEach((route) => { const { methods, path, handler } = route; - methods.forEach(method => { + methods.forEach((method) => { server[method.toLowerCase()](path, handler); }); @@ -176,7 +179,9 @@ module.exports = class DataProvider { #validateOptions(params) { const result = providerOptionsSchema.validate(params); if (result.error) { - throw new Error(`Provider "${this.namespace}" has invalid option: ${result.error.details[0].message}`); + throw new Error( + `Provider "${this.namespace}" has invalid option: ${result.error.details[0].message}`, + ); } } }; @@ -189,4 +194,4 @@ function getProviderName(provider, options) { provider.plugin_name || provider.name ); -} \ No newline at end of file +} diff --git a/packages/core/src/data-provider/index.spec.js b/packages/core/src/data-provider/index.spec.js index f1bd4ddf0..0a0d9f0f4 100644 --- a/packages/core/src/data-provider/index.spec.js +++ b/packages/core/src/data-provider/index.spec.js @@ -3,20 +3,20 @@ const sinon = require('sinon'); const DataProvider = require('./'); class MockProviderPluginController { - getHandler (req, res) { + getHandler(req, res) { res.send('hello'); } - - otherHandler (req, res) { + + otherHandler(req, res) { res.send('other hello'); } } class MockModel { - async getData () { + async getData() { return { type: 'FeatureCollection', - features: [] + features: [], }; } } @@ -26,13 +26,13 @@ class MockOutput { { path: '/mock-output/', methods: ['get', 'post'], - handler: 'pullData' - } + handler: 'pullData', + }, ]; static name = 'MockOutput'; - - async pullData (req, res) { + + async pullData(req, res) { await this.model.pull(req); res.status(200).json({ message: 'success' }); } @@ -47,16 +47,16 @@ const mockPluginDefinition = { { path: '/mock-provider-route/:id', methods: ['get'], - handler: 'getHandler' - } + handler: 'getHandler', + }, ], - Model: MockModel + Model: MockModel, }; describe('Tests for Provider', function () { const mockCache = {}; const mockLogger = { - info: () => {} + info: () => {}, }; it('should create instance of DataProvider', function () { @@ -70,11 +70,22 @@ describe('Tests for Provider', function () { providerRegistration.should.have.property('namespace', 'test-provider'); providerRegistration.should.have.property('version', '99.0.0'); providerRegistration.should.have.property('providerRoutes').length(1); - providerRegistration.providerRoutes[0].should.have.property('path', '/mock-provider-route/:id'); + providerRegistration.providerRoutes[0].should.have.property( + 'path', + '/mock-provider-route/:id', + ); providerRegistration.should.have.property('outputPluginRoutes').length(1); - providerRegistration.outputPluginRoutes[0].should.have.property('namespace', 'MockOutput'); - providerRegistration.outputPluginRoutes[0].should.have.property('routes').length(1); - providerRegistration.outputPluginRoutes[0].routes[0].should.have.property('path', '/test-provider/:id/mock-output'); + providerRegistration.outputPluginRoutes[0].should.have.property( + 'namespace', + 'MockOutput', + ); + providerRegistration.outputPluginRoutes[0].should.have + .property('routes') + .length(1); + providerRegistration.outputPluginRoutes[0].routes[0].should.have.property( + 'path', + '/test-provider/:id/mock-output', + ); }); it('should create instance of DataProvider with unknown version number', function () { @@ -117,14 +128,18 @@ describe('Tests for Provider', function () { const mockServer = { get: sinon.spy(), - post: sinon.spy() + post: sinon.spy(), }; providerRegistration.addRoutesToServer(mockServer); mockServer.get.callCount.should.equal(2); mockServer.get.firstCall.args[0].should.equal('/mock-provider-route/:id'); - mockServer.get.secondCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.get.secondCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); mockServer.post.callCount.should.equal(1); - mockServer.post.firstCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.post.firstCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); }); it('should add routes to server, provider routes last', function () { @@ -133,19 +148,23 @@ describe('Tests for Provider', function () { cache: mockCache, outputPlugins: [{ outputClass: MockOutput }], pluginDefinition: { ...mockPluginDefinition }, - options: { defaultToOutputRoutes: true } + options: { defaultToOutputRoutes: true }, }); const mockServer = { get: sinon.spy(), - post: sinon.spy() + post: sinon.spy(), }; providerRegistration.addRoutesToServer(mockServer); mockServer.get.callCount.should.equal(2); - mockServer.get.firstCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.get.firstCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); mockServer.get.secondCall.args[0].should.equal('/mock-provider-route/:id'); mockServer.post.callCount.should.equal(1); - mockServer.post.firstCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.post.firstCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); }); it('should add routes to server, no provider-defined routes', function () { @@ -154,18 +173,22 @@ describe('Tests for Provider', function () { cache: mockCache, outputPlugins: [{ outputClass: MockOutput }], pluginDefinition: { ...mockPluginDefinition, routes: undefined }, - options: { defaultToOutputRoutes: true } + options: { defaultToOutputRoutes: true }, }); const mockServer = { get: sinon.spy(), - post: sinon.spy() + post: sinon.spy(), }; providerRegistration.addRoutesToServer(mockServer); mockServer.get.callCount.should.equal(1); - mockServer.get.firstCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.get.firstCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); mockServer.post.callCount.should.equal(1); - mockServer.post.firstCall.args[0].should.equal('/test-provider/:id/mock-output'); + mockServer.post.firstCall.args[0].should.equal( + '/test-provider/:id/mock-output', + ); }); it('should throw error on bad provider option', () => { @@ -175,10 +198,12 @@ describe('Tests for Provider', function () { cache: mockCache, outputPlugins: [{ outputClass: MockOutput }], pluginDefinition: { ...mockPluginDefinition }, - options: { routePrefix: 99 } + options: { routePrefix: 99 }, }); } catch (error) { - error.message.should.equal('Provider "test-provider" has invalid option: "routePrefix" must be a string'); + error.message.should.equal( + 'Provider "test-provider" has invalid option: "routePrefix" must be a string', + ); } }); }); diff --git a/packages/core/src/data-provider/provider-route.js b/packages/core/src/data-provider/provider-route.js index 43ecae659..9de0c4bc7 100644 --- a/packages/core/src/data-provider/provider-route.js +++ b/packages/core/src/data-provider/provider-route.js @@ -7,7 +7,6 @@ const METHODS_SCHEMA = Joi.array().items( ); class ProviderRoute { - constructor(params) { const { handler, path, controller, methods } = params; this.#validateHttpMethods(methods, path); @@ -19,7 +18,7 @@ class ProviderRoute { this.path = composeRoutePath(params); } - #validateController (controller, handler, path) { + #validateController(controller, handler, path) { if (!controller[handler]) { throw new Error( `defines route "${path}" with unknown handler: ${handler}`, @@ -27,7 +26,7 @@ class ProviderRoute { } } - #validateHttpMethods (methods, path) { + #validateHttpMethods(methods, path) { const result = METHODS_SCHEMA.validate(methods); if (result.error) { throw new Error( diff --git a/packages/core/src/data-provider/provider-route.spec.js b/packages/core/src/data-provider/provider-route.spec.js index 72a7e647a..a59658ac5 100644 --- a/packages/core/src/data-provider/provider-route.spec.js +++ b/packages/core/src/data-provider/provider-route.spec.js @@ -1,14 +1,14 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const proxyquire = require('proxyquire'); const ProviderRoute = proxyquire('./provider-route', { './helpers/compose-route-path': () => { return 'the/path/for/route'; - } + }, }); describe('ProviderRoute', function () { it('should create instance of ProviderRoute', function () { - const controller = { someHandler: () => {} }; + const controller = { someHandler: () => {} }; const providerRoute = new ProviderRoute({ controller, handler: 'someHandler', @@ -25,7 +25,7 @@ describe('ProviderRoute', function () { }); it('should fail HTTP method validation', function () { - const controller = { someHandler: () => {} }; + const controller = { someHandler: () => {} }; try { new ProviderRoute({ controller, @@ -36,12 +36,14 @@ describe('ProviderRoute', function () { routePrefix: 'cantaloupe', }); } catch (error) { - error.message.should.equal('defines route "some-route/:id" with unsupported HTTP method: poszt'); - } + error.message.should.equal( + 'defines route "some-route/:id" with unsupported HTTP method: poszt', + ); + } }); it('should fail controller validation', function () { - const controller = { someHandler: () => {} }; + const controller = { someHandler: () => {} }; try { new ProviderRoute({ controller, @@ -52,7 +54,9 @@ describe('ProviderRoute', function () { routePrefix: 'cantaloupe', }); } catch (error) { - error.message.should.equal('defines route "some-route/:id" with unknown handler: someOtherHandler'); - } + error.message.should.equal( + 'defines route "some-route/:id" with unknown handler: someOtherHandler', + ); + } }); }); diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 03a993869..ab57e0a64 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -34,8 +34,8 @@ class Koop extends Events { this.register(geoservices, { logger: this.log, authInfo: this.config.authInfo, - defaults: geoservicesDefaults - }); + defaults: geoservicesDefaults, + }); } this.server @@ -44,9 +44,11 @@ class Koop extends Events { `Koop ${this.version} mounted at ${this.server.mountpath}`, ); }) - .get('/status', (req, res) => res.json({ - success: true - })); + .get('/status', (req, res) => + res.json({ + success: true, + }), + ); } register(plugin, options) { @@ -105,8 +107,8 @@ class Koop extends Events { this.cache = new Cache({ logger: options?.logger || this.log, options }); this.log.info(`registered cache: ${Cache.name} v${Cache.version}`); } - - #registerAuth (auth) { + + #registerAuth(auth) { this.#authModule = auth; this.log.info(`registered auth module: ${auth.name} v${auth.version}`); } diff --git a/packages/core/src/index.spec.js b/packages/core/src/index.spec.js index 74afc0b69..33b46dbef 100644 --- a/packages/core/src/index.spec.js +++ b/packages/core/src/index.spec.js @@ -14,7 +14,7 @@ const mockApp = { return mockApp; }), get: sinon.spy((route, handler) => { - if( route === '/status') { + if (route === '/status') { handler({}, { json: () => {} }); } return mockApp; @@ -34,33 +34,33 @@ class mockDataProviderModule extends DataProvider { } class MockLogger { - warn () {} - log () {} - error () {} - info () {} - silly () {} + warn() {} + log() {} + error() {} + info() {} + silly() {} } const Koop = proxyquire('./', { './data-provider': mockDataProviderModule, '@koopjs/logger': MockLogger, - 'express': mockExpress + express: mockExpress, }); class MockProviderPluginController { - getHandler (req, res) { + getHandler(req, res) { res.send('hello'); } - - otherHandler (req, res) { + + otherHandler(req, res) { res.send('other hello'); } } class MockModel { - async getData () { + async getData() { return { type: 'FeatureCollection', - features: [] + features: [], }; } } @@ -74,13 +74,13 @@ const mockProviderDefinition = { { path: '/mock-provider-route/:id', methods: ['get'], - handler: 'getHandler' - } + handler: 'getHandler', + }, ], - Model: MockModel + Model: MockModel, }; -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line describe('Index tests', function () { beforeEach(() => { @@ -99,7 +99,7 @@ describe('Index tests', function () { }); it('should skip geoservices registration', function () { - const koop = new Koop({ skipGeoservicesRegistration: true}); + const koop = new Koop({ skipGeoservicesRegistration: true }); koop.register(mockProviderDefinition, { routePrefix: 'watermelon' }); koop.outputs.length.should.equal(0); }); @@ -118,7 +118,10 @@ describe('Index tests', function () { koop.register(); throw new Error('should have thrown'); } catch (error) { - error.should.have.property('message', 'Plugin registration failed: plugin undefined'); + error.should.have.property( + 'message', + 'Plugin registration failed: plugin undefined', + ); } }); @@ -131,7 +134,7 @@ describe('Index tests', function () { it('should register unknown plugin type as provider and add output and provider routes to router stack', function () { const koop = new Koop({ logLevel: 'error' }); - const unknownPlugin = _.cloneDeep(mockProviderDefinition); + const unknownPlugin = _.cloneDeep(mockProviderDefinition); delete unknownPlugin.type; koop.register(unknownPlugin, { routePrefix: 'watermelon' }); @@ -143,32 +146,28 @@ describe('Index tests', function () { const mockAuthPlugin = { type: 'auth', authenticate: function () {}, - authorize: function () {} + authorize: function () {}, }; - + const koop = new Koop({ logLevel: 'error' }); try { koop.register(mockAuthPlugin); } catch (error) { - (error).should.equal(undefined); + error.should.equal(undefined); } - }); it('should register cache-plugin successfully', function () { const mockCachePlugin = class MockCache { static type = 'cache'; }; - + const koop = new Koop({ logLevel: 'error' }); try { koop.register(mockCachePlugin); } catch (error) { - (error).should.equal(undefined); + error.should.equal(undefined); } - }); }); - }); - diff --git a/packages/featureserver/src/generate-renderer/color-ramp.js b/packages/featureserver/src/generate-renderer/color-ramp.js index 8e6e90148..216a52373 100644 --- a/packages/featureserver/src/generate-renderer/color-ramp.js +++ b/packages/featureserver/src/generate-renderer/color-ramp.js @@ -3,14 +3,14 @@ const { CodedError } = require('../helpers/errors'); module.exports = { createColorRamp }; -function createColorRamp (params = {}) { +function createColorRamp(params = {}) { const { classification, colorRamps, type = 'algorithmic', fromColor = [0, 255, 0], toColor = [0, 0, 255], - algorithm = 'HSVAlgorithm' + algorithm = 'HSVAlgorithm', } = params; if (!classification || classification.length === 0) { @@ -22,35 +22,38 @@ function createColorRamp (params = {}) { fromColor, toColor, algorithm, - classificationCount: classification.length + classificationCount: classification.length, }); } if (type === 'multipart') { - return createMultipartRamp({ colorRamps, classificationCount: classification.length }); + return createMultipartRamp({ + colorRamps, + classificationCount: classification.length, + }); } throw new CodedError(`Invalid color ramp type: ${type}`, 400); } -function createMultipartRamp (options) { +function createMultipartRamp(options) { const { colorRamps, classificationCount } = options; if (!colorRamps || !Array.isArray(colorRamps)) { throw new CodedError( - 'Multipart color-ramps need a valid color-ramp configuration array' + 'Multipart color-ramps need a valid color-ramp configuration array', ); } return colorRamps.map((ramp) => { return createAlgorithmicRamp({ ...ramp, - classificationCount + classificationCount, }); }); } -function createAlgorithmicRamp (options) { +function createAlgorithmicRamp(options) { const { fromColor, toColor, algorithm, classificationCount } = options; const colorRamp = chroma.scale([fromColor.slice(0, 3), toColor.slice(0, 3)]); diff --git a/packages/featureserver/src/generate-renderer/color-ramp.spec.js b/packages/featureserver/src/generate-renderer/color-ramp.spec.js index 50c0497ae..183268b2e 100644 --- a/packages/featureserver/src/generate-renderer/color-ramp.spec.js +++ b/packages/featureserver/src/generate-renderer/color-ramp.spec.js @@ -1,7 +1,5 @@ const should = require('should'); // eslint-disable-line -const { - createColorRamp -} = require('./color-ramp'); +const { createColorRamp } = require('./color-ramp'); const classification = [ [80, 147], @@ -12,7 +10,7 @@ const classification = [ [307, 360], [360, 558], [558, 799], - [799, 2000] + [799, 2000], ]; describe('when creating a color ramp that', () => { @@ -22,11 +20,15 @@ describe('when creating a color ramp that', () => { }); it('should throw an error on invalid type option', () => { - createColorRamp.bind(null, { classification, type: 'foo' }).should.throw(); + createColorRamp + .bind(null, { classification, type: 'foo' }) + .should.throw(); }); it('should throw an error on multipart type with color-ramps', () => { - createColorRamp.bind(null, { classification, type: 'multipart' }).should.throw(); + createColorRamp + .bind(null, { classification, type: 'multipart' }) + .should.throw(); }); it('should return correct hsv color ramp', () => { @@ -35,7 +37,7 @@ describe('when creating a color ramp that', () => { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriHSVAlgorithm' + algorithm: 'esriHSVAlgorithm', }); response.should.deepEqual([ [0, 255, 0], @@ -46,7 +48,7 @@ describe('when creating a color ramp that', () => { [0, 191, 255], [0, 127, 255], [0, 64, 255], - [0, 0, 255] + [0, 0, 255], ]); }); @@ -56,7 +58,7 @@ describe('when creating a color ramp that', () => { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriCIELabAlgorithm' + algorithm: 'esriCIELabAlgorithm', }); response.should.deepEqual([ [0, 255, 0], @@ -67,7 +69,7 @@ describe('when creating a color ramp that', () => { [121, 120, 189], [108, 91, 211], [83, 58, 233], - [0, 0, 255] + [0, 0, 255], ]); }); @@ -77,7 +79,7 @@ describe('when creating a color ramp that', () => { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriLabLChAlgorithm' + algorithm: 'esriLabLChAlgorithm', }); response.should.deepEqual([ [0, 255, 0], @@ -88,7 +90,7 @@ describe('when creating a color ramp that', () => { [0, 163, 255], [0, 135, 255], [0, 96, 255], - [0, 0, 255] + [0, 0, 255], ]); }); @@ -100,21 +102,21 @@ describe('when creating a color ramp that', () => { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriHSVAlgorithm' + algorithm: 'esriHSVAlgorithm', }, { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriCIELabAlgorithm' + algorithm: 'esriCIELabAlgorithm', }, { type: 'algorithmic', fromColor: [0, 255, 0], toColor: [0, 0, 255], - algorithm: 'esriLabLChAlgorithm' - } - ] + algorithm: 'esriLabLChAlgorithm', + }, + ], }; const response = createColorRamp({ classification, ...multipartRamp }); response.should.deepEqual([ @@ -127,7 +129,7 @@ describe('when creating a color ramp that', () => { [0, 191, 255], [0, 127, 255], [0, 64, 255], - [0, 0, 255] + [0, 0, 255], ], [ [0, 255, 0], @@ -138,7 +140,7 @@ describe('when creating a color ramp that', () => { [121, 120, 189], [108, 91, 211], [83, 58, 233], - [0, 0, 255] + [0, 0, 255], ], [ [0, 255, 0], @@ -149,8 +151,8 @@ describe('when creating a color ramp that', () => { [0, 163, 255], [0, 135, 255], [0, 96, 255], - [0, 0, 255] - ] + [0, 0, 255], + ], ]); }); }); diff --git a/packages/featureserver/src/generate-renderer/create-symbol.js b/packages/featureserver/src/generate-renderer/create-symbol.js index 11cd2fbe1..021bf6eea 100644 --- a/packages/featureserver/src/generate-renderer/create-symbol.js +++ b/packages/featureserver/src/generate-renderer/create-symbol.js @@ -1,24 +1,23 @@ -const { - PointRenderer, - LineRenderer, - PolygonRenderer -} = require('../helpers'); +const { PointRenderer, LineRenderer, PolygonRenderer } = require('../helpers'); const { CodedError } = require('../helpers/errors'); module.exports = { createSymbol }; -function createSymbol (baseSymbol, color, geomType) { +function createSymbol(baseSymbol, color, geomType) { const symbol = baseSymbol || getDefaultSymbol(geomType); return { ...symbol, color }; } -function getDefaultSymbol (geomType) { +function getDefaultSymbol(geomType) { const { symbol } = getSymbolRenderer(geomType); return symbol; } -function getSymbolRenderer (geomType) { - if (geomType === 'esriGeometryPoint' || geomType === 'esriGeometryMultiPoint') { +function getSymbolRenderer(geomType) { + if ( + geomType === 'esriGeometryPoint' || + geomType === 'esriGeometryMultiPoint' + ) { return new PointRenderer(); } @@ -30,5 +29,8 @@ function getSymbolRenderer (geomType) { return new PolygonRenderer(); } - throw new CodedError('Dataset geometry type is not supported for renderers.', 400); + throw new CodedError( + 'Dataset geometry type is not supported for renderers.', + 400, + ); } diff --git a/packages/featureserver/src/generate-renderer/create-symbol.spec.js b/packages/featureserver/src/generate-renderer/create-symbol.spec.js index f29ad7322..9c74576fb 100644 --- a/packages/featureserver/src/generate-renderer/create-symbol.spec.js +++ b/packages/featureserver/src/generate-renderer/create-symbol.spec.js @@ -1,7 +1,5 @@ -const should = require('should'); // eslint-disable-line -const { - createSymbol -} = require('./create-symbol'); +const should = require('should'); +const { createSymbol } = require('./create-symbol'); describe('when creating a symbol', () => { it('uses passed in base symbol and color', () => { @@ -14,7 +12,9 @@ describe('when creating a symbol', () => { createSymbol(undefined, 'red'); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Dataset geometry type is not supported for renderers.'); + error.message.should.equal( + 'Dataset geometry type is not supported for renderers.', + ); error.code.should.equal(400); } }); @@ -24,19 +24,14 @@ describe('when creating a symbol', () => { result.should.deepEqual({ color: 'red', outline: { - color: [ - 190, - 190, - 190, - 105 - ], + color: [190, 190, 190, 105], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, size: 7.5, type: 'esriSMS', - style: 'esriSMSCircle' + style: 'esriSMSCircle', }); }); @@ -45,19 +40,14 @@ describe('when creating a symbol', () => { result.should.deepEqual({ color: 'red', outline: { - color: [ - 190, - 190, - 190, - 105 - ], + color: [190, 190, 190, 105], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, size: 7.5, type: 'esriSMS', - style: 'esriSMSCircle' + style: 'esriSMSCircle', }); }); @@ -67,7 +57,7 @@ describe('when creating a symbol', () => { color: 'red', width: 6.999999999999999, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }); }); @@ -76,18 +66,13 @@ describe('when creating a symbol', () => { result.should.deepEqual({ color: 'red', outline: { - color: [ - 150, - 150, - 150, - 155 - ], + color: [150, 150, 150, 155], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, type: 'esriSFS', - style: 'esriSFSSolid' + style: 'esriSFSSolid', }); }); }); diff --git a/packages/featureserver/src/generate-renderer/index.js b/packages/featureserver/src/generate-renderer/index.js index 28e7cbf5b..51f92b33b 100644 --- a/packages/featureserver/src/generate-renderer/index.js +++ b/packages/featureserver/src/generate-renderer/index.js @@ -6,13 +6,16 @@ const { createSymbol } = require('./create-symbol'); module.exports = generateRenderer; -function generateRenderer (data = {}, options = {}) { +function generateRenderer(data = {}, options = {}) { const { statistics = {}, features } = data; const geometryType = getGeometryTypeFromGeojson(data); const { classificationDef = {} } = options; if (statistics.classBreaks) { - return generateRendererFromPrecalculatedStatistics(statistics, { classificationDef, geometryType }); + return generateRendererFromPrecalculatedStatistics(statistics, { + classificationDef, + geometryType, + }); } if (features) { @@ -22,12 +25,16 @@ function generateRenderer (data = {}, options = {}) { return {}; } -function generateRendererFromPrecalculatedStatistics (statistics, options) { +function generateRendererFromPrecalculatedStatistics(statistics, options) { const { classificationDef, geometryType = 'esriGeometryPoint' } = options; const { colorRamp: colorRampConfig = {}, baseSymbol } = classificationDef; const classification = statistics.classBreaks.sort((a, b) => a[0] - b[0]); - validateClassificationDefinition(classificationDef, geometryType, classification); + validateClassificationDefinition( + classificationDef, + geometryType, + classification, + ); const colorRamp = createColorRamp({ classification, ...colorRampConfig }); const symbolCollection = colorRamp.map((color) => { @@ -36,13 +43,17 @@ function generateRendererFromPrecalculatedStatistics (statistics, options) { return renderClassBreaks(classification, classificationDef, symbolCollection); } -function generateRendererFromFeatures (data, params) { +function generateRendererFromFeatures(data, params) { const { classificationDef, geometryType } = params; // TODO: this seems weird; the winnow method is "query" but it's really a very specialized transform (aggregation) // consider changes to winnow - this should maybe be a different method const classification = Winnow.query(data, params); - validateClassificationDefinition(classificationDef, geometryType, classification); + validateClassificationDefinition( + classificationDef, + geometryType, + classification, + ); const { colorRamp: colorRampConfig = {}, baseSymbol } = classificationDef; @@ -52,36 +63,44 @@ function generateRendererFromFeatures (data, params) { }); if (classificationDef.type === 'classBreaksDef') { - return renderClassBreaks(classification, classificationDef, symbolCollection); + return renderClassBreaks( + classification, + classificationDef, + symbolCollection, + ); } // if not 'classBreaksDef', then its unique-values return renderUniqueValue(classification, classificationDef, symbolCollection); } -function renderClassBreaks (breaks, classificationDef, symbolCollection) { +function renderClassBreaks(breaks, classificationDef, symbolCollection) { return { type: 'classBreaks', field: classificationDef.classificationField || '', classificationMethod: classificationDef.classificationMethod || '', minValue: breaks[0][0], - classBreakInfos: createClassBreakInfos(breaks, symbolCollection) + classBreakInfos: createClassBreakInfos(breaks, symbolCollection), }; } -function createClassBreakInfos (breaks, symbolCollection) { +function createClassBreakInfos(breaks, symbolCollection) { return breaks.map((classBreak, index) => { return { classMinValue: classBreak[0], classMaxValue: classBreak[1], label: `${classBreak[0]}-${classBreak[1]}`, description: '', - symbol: symbolCollection[index] + symbol: symbolCollection[index], }; }); } -function renderUniqueValue (classification, classificationDef, symbolCollection) { +function renderUniqueValue( + classification, + classificationDef, + symbolCollection, +) { const { uniqueValueFields, fieldDelimiter } = classificationDef; return { type: 'uniqueValue', @@ -94,15 +113,15 @@ function renderUniqueValue (classification, classificationDef, symbolCollection) uniqueValueInfos: createUniqueValueInfos( classification, fieldDelimiter, - symbolCollection - ) + symbolCollection, + ), }; } -function createUniqueValueInfos ( +function createUniqueValueInfos( uniqueValueEntries, fieldDelimiter, - symbolCollection + symbolCollection, ) { return uniqueValueEntries.map((uniqueValue, index) => { const value = serializeUniqueValues(uniqueValue, fieldDelimiter); @@ -112,12 +131,12 @@ function createUniqueValueInfos ( count: uniqueValue.count, label: value, description: '', - symbol: symbolCollection[index] + symbol: symbolCollection[index], }; }); } -function serializeUniqueValues (uniqueValue, delimiter) { +function serializeUniqueValues(uniqueValue, delimiter) { const { count, ...rest } = uniqueValue; return Object.values(rest).join(delimiter); } diff --git a/packages/featureserver/src/generate-renderer/index.spec.js b/packages/featureserver/src/generate-renderer/index.spec.js index 4b1cb5b4f..86e73bce7 100644 --- a/packages/featureserver/src/generate-renderer/index.spec.js +++ b/packages/featureserver/src/generate-renderer/index.spec.js @@ -1,4 +1,4 @@ -const should = require('should'); // eslint-disable-line +const should = require('should'); const proxyquire = require('proxyquire'); const sinon = require('sinon'); @@ -27,14 +27,14 @@ describe('generate-renderer', () => { const generateRenderer = proxyquire('./', { '../helpers': { - getGeometryTypeFromGeojson: getGeometrySpy + getGeometryTypeFromGeojson: getGeometrySpy, }, './create-symbol': { - createSymbol: createSymbolSpy + createSymbol: createSymbolSpy, }, './color-ramp': { - createColorRamp: createColorRampSpy - } + createColorRamp: createColorRampSpy, + }, }); const data = { @@ -42,9 +42,9 @@ describe('generate-renderer', () => { classBreaks: [ [0, 10], [21, 30], - [11, 20] - ] - } + [11, 20], + ], + }, }; const result = generateRenderer(data); @@ -59,48 +59,46 @@ describe('generate-renderer', () => { classMaxValue: 10, label: '0-10', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 11, classMaxValue: 20, label: '11-20', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 21, classMaxValue: 30, label: '21-30', description: '', - symbol: undefined - } - ] + symbol: undefined, + }, + ], }); getGeometrySpy.calledOnce.should.equal(true); getGeometrySpy.firstCall.args.should.deepEqual([data]); createColorRampSpy.calledOnce.should.equal(true); createColorRampSpy.firstCall.args.should.deepEqual([ - { classification: data.statistics.classBreaks } + { classification: data.statistics.classBreaks }, ]); createSymbolSpy.calledTwice.should.equal(true); createSymbolSpy.firstCall.args.should.deepEqual([ undefined, 'color-1', - 'esriGeometryPoint' + 'esriGeometryPoint', ]); createSymbolSpy.secondCall.args.should.deepEqual([ undefined, 'color-2', - 'esriGeometryPoint' + 'esriGeometryPoint', ]); }); it('should render precalculated statistics with default geometry type', () => { - const getGeometrySpy = sinon.spy(function () { - - }); + const getGeometrySpy = sinon.spy(function () {}); const createSymbolSpy = sinon.spy(function () { return 'symbol'; @@ -112,14 +110,14 @@ describe('generate-renderer', () => { const generateRenderer = proxyquire('./', { '../helpers': { - getGeometryTypeFromGeojson: getGeometrySpy + getGeometryTypeFromGeojson: getGeometrySpy, }, './create-symbol': { - createSymbol: createSymbolSpy + createSymbol: createSymbolSpy, }, './color-ramp': { - createColorRamp: createColorRampSpy - } + createColorRamp: createColorRampSpy, + }, }); const data = { @@ -127,9 +125,9 @@ describe('generate-renderer', () => { classBreaks: [ [0, 10], [21, 30], - [11, 20] - ] - } + [11, 20], + ], + }, }; const result = generateRenderer(data); @@ -144,41 +142,41 @@ describe('generate-renderer', () => { classMaxValue: 10, label: '0-10', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 11, classMaxValue: 20, label: '11-20', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 21, classMaxValue: 30, label: '21-30', description: '', - symbol: undefined - } - ] + symbol: undefined, + }, + ], }); getGeometrySpy.calledOnce.should.equal(true); getGeometrySpy.firstCall.args.should.deepEqual([data]); createColorRampSpy.calledOnce.should.equal(true); createColorRampSpy.firstCall.args.should.deepEqual([ - { classification: data.statistics.classBreaks } + { classification: data.statistics.classBreaks }, ]); createSymbolSpy.calledTwice.should.equal(true); createSymbolSpy.firstCall.args.should.deepEqual([ undefined, 'color-1', - 'esriGeometryPoint' + 'esriGeometryPoint', ]); createSymbolSpy.secondCall.args.should.deepEqual([ undefined, 'color-2', - 'esriGeometryPoint' + 'esriGeometryPoint', ]); }); }); @@ -189,7 +187,7 @@ describe('generate-renderer', () => { return [ [0, 10], [11, 20], - [21, 30] + [21, 30], ]; }); @@ -199,12 +197,14 @@ describe('generate-renderer', () => { const generateRenderer = proxyquire('./', { '@koopjs/winnow': { - query: winnowSpy + query: winnowSpy, }, '../helpers': { - getGeometryTypeFromGeojson: getGeometrySpy + getGeometryTypeFromGeojson: getGeometrySpy, + }, + './validate-classification-definition': () => { + throw new Error('invalid classification definition'); }, - './validate-classification-definition': () => { throw new Error('invalid classification definition'); } }); try { @@ -220,7 +220,7 @@ describe('generate-renderer', () => { return [ [0, 10], [11, 20], - [21, 30] + [21, 30], ]; }); @@ -238,15 +238,15 @@ describe('generate-renderer', () => { const generateRenderer = proxyquire('./', { '@koopjs/winnow': { - query: winnowSpy + query: winnowSpy, }, '../helpers': { - getGeometryTypeFromGeojson: getGeometrySpy + getGeometryTypeFromGeojson: getGeometrySpy, }, './color-ramp': { - createColorRamp: createColorRampSpy + createColorRamp: createColorRampSpy, }, - './create-symbol': { createSymbol: createSymbolSpy } + './create-symbol': { createSymbol: createSymbolSpy }, }); const result = generateRenderer( @@ -255,9 +255,9 @@ describe('generate-renderer', () => { classificationDef: { type: 'classBreaksDef', classificationField: 'classification-field', - classificationMethod: 'classification-method' - } - } + classificationMethod: 'classification-method', + }, + }, ); result.should.deepEqual({ @@ -271,28 +271,28 @@ describe('generate-renderer', () => { classMaxValue: 10, label: '0-10', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 11, classMaxValue: 20, label: '11-20', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { classMinValue: 21, classMaxValue: 30, label: '21-30', description: '', - symbol: undefined - } - ] + symbol: undefined, + }, + ], }); getGeometrySpy.calledOnce.should.equal(true); getGeometrySpy.firstCall.args.should.deepEqual([ - { features: ['feature'] } + { features: ['feature'] }, ]); winnowSpy.calledOnce.should.equal(true); winnowSpy.firstCall.args.should.deepEqual([ @@ -301,10 +301,10 @@ describe('generate-renderer', () => { classificationDef: { type: 'classBreaksDef', classificationField: 'classification-field', - classificationMethod: 'classification-method' + classificationMethod: 'classification-method', }, - geometryType: 'esriGeometryPoint' - } + geometryType: 'esriGeometryPoint', + }, ]); }); @@ -313,16 +313,16 @@ describe('generate-renderer', () => { return [ { count: 80, - Genus: 'MAGNOLIA' + Genus: 'MAGNOLIA', }, { count: 77, - Genus: 'QUERCUS' + Genus: 'QUERCUS', }, { count: 24, - Genus: 'JACARANDA' - } + Genus: 'JACARANDA', + }, ]; }); @@ -340,15 +340,15 @@ describe('generate-renderer', () => { const generateRenderer = proxyquire('./', { '@koopjs/winnow': { - query: winnowSpy + query: winnowSpy, }, '../helpers': { - getGeometryTypeFromGeojson: getGeometrySpy + getGeometryTypeFromGeojson: getGeometrySpy, }, './color-ramp': { - createColorRamp: createColorRampSpy + createColorRamp: createColorRampSpy, }, - './create-symbol': { createSymbol: createSymbolSpy } + './create-symbol': { createSymbol: createSymbolSpy }, }); const result = generateRenderer( @@ -357,9 +357,9 @@ describe('generate-renderer', () => { classificationDef: { type: 'uniqueValueDef', uniqueValueFields: ['Genus'], - fieldDelimiter: ',' - } - } + fieldDelimiter: ',', + }, + }, ); result.should.deepEqual({ @@ -368,8 +368,7 @@ describe('generate-renderer', () => { field2: '', field3: '', fieldDelimiter: ',', - defaultSymbol: { - }, + defaultSymbol: {}, defaultLabel: '', uniqueValueInfos: [ { @@ -377,28 +376,28 @@ describe('generate-renderer', () => { count: 80, label: 'MAGNOLIA', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { value: 'QUERCUS', count: 77, label: 'QUERCUS', description: '', - symbol: 'symbol' + symbol: 'symbol', }, { value: 'JACARANDA', count: 24, label: 'JACARANDA', description: '', - symbol: undefined - } - ] + symbol: undefined, + }, + ], }); getGeometrySpy.calledOnce.should.equal(true); getGeometrySpy.firstCall.args.should.deepEqual([ - { features: ['feature'] } + { features: ['feature'] }, ]); winnowSpy.calledOnce.should.equal(true); winnowSpy.firstCall.args.should.deepEqual([ @@ -407,10 +406,10 @@ describe('generate-renderer', () => { classificationDef: { type: 'uniqueValueDef', fieldDelimiter: ',', - uniqueValueFields: ['Genus'] + uniqueValueFields: ['Genus'], }, - geometryType: 'esriGeometryPoint' - } + geometryType: 'esriGeometryPoint', + }, ]); }); }); diff --git a/packages/featureserver/src/generate-renderer/validate-classification-definition.spec.js b/packages/featureserver/src/generate-renderer/validate-classification-definition.spec.js index 40a83b27b..326bc7a38 100644 --- a/packages/featureserver/src/generate-renderer/validate-classification-definition.spec.js +++ b/packages/featureserver/src/generate-renderer/validate-classification-definition.spec.js @@ -1,4 +1,4 @@ -const should = require('should'); // eslint-disable-line +const should = require('should'); const validateClassificationDefinition = require('./validate-classification-definition'); describe('when creating a symbol', () => { @@ -24,60 +24,90 @@ describe('when creating a symbol', () => { it('throws error with unknown base symbol type', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'foo' } }); + validateClassificationDefinition({ + type: 'classBreaksDef', + baseSymbol: { type: 'foo' }, + }); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('baseSymbol requires a valid type: esriSMS, esriSLS, esriSFS'); + error.message.should.equal( + 'baseSymbol requires a valid type: esriSMS, esriSLS, esriSFS', + ); error.code.should.equal(400); } }); it('throws error with undefined base symbol type', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: {} }); + validateClassificationDefinition({ + type: 'classBreaksDef', + baseSymbol: {}, + }); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('baseSymbol requires a valid type: esriSMS, esriSLS, esriSFS'); + error.message.should.equal( + 'baseSymbol requires a valid type: esriSMS, esriSLS, esriSFS', + ); error.code.should.equal(400); } }); it('throws error with base symbol type / geometry: line/sms', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, 'esriGeometryPolyline'); + validateClassificationDefinition( + { type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, + 'esriGeometryPolyline', + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Classification defintion uses a base symbol type that is incompatiable with dataset geometry'); + error.message.should.equal( + 'Classification defintion uses a base symbol type that is incompatiable with dataset geometry', + ); error.code.should.equal(400); } }); it('throws error with base symbol type / geometry: polygon/sms', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, 'esriGeometryPolygon'); + validateClassificationDefinition( + { type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, + 'esriGeometryPolygon', + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Classification defintion uses a base symbol type that is incompatiable with dataset geometry'); + error.message.should.equal( + 'Classification defintion uses a base symbol type that is incompatiable with dataset geometry', + ); error.code.should.equal(400); } }); it('throws error with base symbol type / geometry: point/sls', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'esriSLS' } }, 'esriGeometryPoint'); + validateClassificationDefinition( + { type: 'classBreaksDef', baseSymbol: { type: 'esriSLS' } }, + 'esriGeometryPoint', + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Classification defintion uses a base symbol type that is incompatiable with dataset geometry'); + error.message.should.equal( + 'Classification defintion uses a base symbol type that is incompatiable with dataset geometry', + ); error.code.should.equal(400); } }); it('throws error with unsupport geometry', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'esriSLS' } }, 'foo'); + validateClassificationDefinition( + { type: 'classBreaksDef', baseSymbol: { type: 'esriSLS' } }, + 'foo', + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Classification defintion uses a base symbol type that is incompatiable with dataset geometry'); + error.message.should.equal( + 'Classification defintion uses a base symbol type that is incompatiable with dataset geometry', + ); error.code.should.equal(400); } }); @@ -92,7 +122,10 @@ describe('when creating a symbol', () => { it('validates with base symbol / geometry match', () => { try { - validateClassificationDefinition({ type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, 'esriGeometryPoint'); + validateClassificationDefinition( + { type: 'classBreaksDef', baseSymbol: { type: 'esriSMS' } }, + 'esriGeometryPoint', + ); } catch (error) { should.fail(`should not have thrown error: ${error}`); } @@ -100,20 +133,32 @@ describe('when creating a symbol', () => { it('throws error when unique-value-fields definition is missing uniqueValueFields array', () => { try { - validateClassificationDefinition({ type: 'uniqueValueDef' }, 'esriGeometryPoint', [{ fooz: 'bar' }]); + validateClassificationDefinition( + { type: 'uniqueValueDef' }, + 'esriGeometryPoint', + [{ fooz: 'bar' }], + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('uniqueValueDef requires a classification definition with "uniqueValueFields" array'); + error.message.should.equal( + 'uniqueValueDef requires a classification definition with "uniqueValueFields" array', + ); error.code.should.equal(400); } }); it('throws error when unique-value-fields definition diverges from classification', () => { try { - validateClassificationDefinition({ type: 'uniqueValueDef', uniqueValueFields: ['foo'] }, 'esriGeometryPoint', [{ fooz: 'bar' }]); + validateClassificationDefinition( + { type: 'uniqueValueDef', uniqueValueFields: ['foo'] }, + 'esriGeometryPoint', + [{ fooz: 'bar' }], + ); should.fail('should have thrown error'); } catch (error) { - error.message.should.equal('Unique value definition fields are incongruous with classification fields: foo : fooz'); + error.message.should.equal( + 'Unique value definition fields are incongruous with classification fields: foo : fooz', + ); error.code.should.equal(400); } }); diff --git a/packages/featureserver/src/helpers/data-type-utils.js b/packages/featureserver/src/helpers/data-type-utils.js index 820cf249a..50fc18434 100644 --- a/packages/featureserver/src/helpers/data-type-utils.js +++ b/packages/featureserver/src/helpers/data-type-utils.js @@ -7,7 +7,7 @@ const dateTimeParser = require('postgres-date'); const PROBLEMATIC_STRING_SYMBOLS = ['(', '[', '*', '+', '\\', '?']; -function getDataTypeFromValue (value) { +function getDataTypeFromValue(value) { if (_.isNumber(value)) { return Number.isInteger(value) ? 'Integer' : 'Double'; } @@ -19,16 +19,27 @@ function getDataTypeFromValue (value) { return 'String'; } -function isDate (value) { +function isDate(value) { // this is required due to RegExp error in in the iso-datestring-validator module - if (typeof value === 'string' && PROBLEMATIC_STRING_SYMBOLS.includes(value.charAt(0))) { + if ( + typeof value === 'string' && + PROBLEMATIC_STRING_SYMBOLS.includes(value.charAt(0)) + ) { return false; } - return (value instanceof Date || (typeof value === 'string') && !!(dateTimeParser(value) || isValidDate(value) || isValidISODateString(value))); + return ( + value instanceof Date || + (typeof value === 'string' && + !!( + dateTimeParser(value) || + isValidDate(value) || + isValidISODateString(value) + )) + ); } module.exports = { getDataTypeFromValue, - isDate + isDate, }; diff --git a/packages/featureserver/src/helpers/data-type-utils.spec.js b/packages/featureserver/src/helpers/data-type-utils.spec.js index d2fbe2221..1263a4c5d 100644 --- a/packages/featureserver/src/helpers/data-type-utils.spec.js +++ b/packages/featureserver/src/helpers/data-type-utils.spec.js @@ -1,8 +1,5 @@ -const should = require('should') // eslint-disable-line -const { - getDataTypeFromValue, - isDate -} = require('./data-type-utils'); +const should = require('should'); // eslint-disable-line +const { getDataTypeFromValue, isDate } = require('./data-type-utils'); describe('getDataTypeFromValue', () => { it('should return integer', () => { @@ -10,7 +7,7 @@ describe('getDataTypeFromValue', () => { }); it('should return double', () => { - getDataTypeFromValue(10.10).should.equal('Double'); + getDataTypeFromValue(10.1).should.equal('Double'); }); it('should return string', () => { diff --git a/packages/featureserver/src/helpers/errors.js b/packages/featureserver/src/helpers/errors.js index 331a7d351..7bada5972 100644 --- a/packages/featureserver/src/helpers/errors.js +++ b/packages/featureserver/src/helpers/errors.js @@ -1,5 +1,5 @@ class CodedError extends Error { - constructor (message, code) { + constructor(message, code) { super(message); this.name = 'CodedError'; this.code = code || 500; @@ -7,5 +7,5 @@ class CodedError extends Error { } module.exports = { - CodedError + CodedError, }; diff --git a/packages/featureserver/src/helpers/esri-units-lookup.js b/packages/featureserver/src/helpers/esri-units-lookup.js index 671f5c741..7ed98ae48 100644 --- a/packages/featureserver/src/helpers/esri-units-lookup.js +++ b/packages/featureserver/src/helpers/esri-units-lookup.js @@ -30,4 +30,4 @@ function esriUnitsLookup(unit) { } } -module.exports = esriUnitsLookup; \ No newline at end of file +module.exports = esriUnitsLookup; diff --git a/packages/featureserver/src/helpers/esri-units-lookup.spec.js b/packages/featureserver/src/helpers/esri-units-lookup.spec.js index 042c41c5e..aa05cbf74 100644 --- a/packages/featureserver/src/helpers/esri-units-lookup.spec.js +++ b/packages/featureserver/src/helpers/esri-units-lookup.spec.js @@ -16,7 +16,7 @@ describe('esriUnitsLookup', () => { const result = esriUnitsLookup('yard'); result.should.equal('esriYards'); }); - + it('mile', () => { const result = esriUnitsLookup('mile'); result.should.equal('esriMiles'); diff --git a/packages/featureserver/src/helpers/fields/constants.js b/packages/featureserver/src/helpers/fields/constants.js index 60cc2b496..bdf633ecd 100644 --- a/packages/featureserver/src/helpers/fields/constants.js +++ b/packages/featureserver/src/helpers/fields/constants.js @@ -6,5 +6,5 @@ module.exports = { SQL_TYPE_INTEGER: 'sqlTypeInteger', SQL_TYPE_OTHER: 'sqlTypeOther', SQL_TYPE_FLOAT: 'sqlTypeFloat', - OBJECTID_DEFAULT_KEY: 'OBJECTID' + OBJECTID_DEFAULT_KEY: 'OBJECTID', }; diff --git a/packages/featureserver/src/helpers/fields/constants.spec.js b/packages/featureserver/src/helpers/fields/constants.spec.js index b05be0c68..da5e9d854 100644 --- a/packages/featureserver/src/helpers/fields/constants.spec.js +++ b/packages/featureserver/src/helpers/fields/constants.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const { ESRI_FIELD_TYPE_OID, ESRI_FIELD_TYPE_STRING, @@ -7,7 +7,7 @@ const { SQL_TYPE_INTEGER, SQL_TYPE_OTHER, SQL_TYPE_FLOAT, - OBJECTID_DEFAULT_KEY + OBJECTID_DEFAULT_KEY, } = require('./constants'); describe('field constants', () => { diff --git a/packages/featureserver/src/helpers/fields/esri-type-utils.spec.js b/packages/featureserver/src/helpers/fields/esri-type-utils.spec.js index deb02f1d4..285c78c4c 100644 --- a/packages/featureserver/src/helpers/fields/esri-type-utils.spec.js +++ b/packages/featureserver/src/helpers/fields/esri-type-utils.spec.js @@ -1,7 +1,7 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const { getEsriTypeFromDefinition, - getEsriTypeFromValue + getEsriTypeFromValue, } = require('./esri-type-utils'); describe('getEsriTypeFromDefinition', () => { @@ -61,8 +61,12 @@ describe('getEsriTypeFromDefinition', () => { }); it('small-integer', () => { - getEsriTypeFromDefinition('SmallInteger').should.equal('esriFieldTypeSmallInteger'); - getEsriTypeFromDefinition('smallinteger').should.equal('esriFieldTypeSmallInteger'); + getEsriTypeFromDefinition('SmallInteger').should.equal( + 'esriFieldTypeSmallInteger', + ); + getEsriTypeFromDefinition('smallinteger').should.equal( + 'esriFieldTypeSmallInteger', + ); }); it('xml', () => { @@ -91,6 +95,8 @@ describe('getEsriTypeFromValue', () => { it('date', () => { getEsriTypeFromValue(new Date()).should.equal('esriFieldTypeDate'); - getEsriTypeFromValue((new Date()).toISOString()).should.equal('esriFieldTypeDate'); + getEsriTypeFromValue(new Date().toISOString()).should.equal( + 'esriFieldTypeDate', + ); }); }); diff --git a/packages/featureserver/src/helpers/fields/field-classes.js b/packages/featureserver/src/helpers/fields/field-classes.js index 95668da1c..d6a7ea795 100644 --- a/packages/featureserver/src/helpers/fields/field-classes.js +++ b/packages/featureserver/src/helpers/fields/field-classes.js @@ -1,6 +1,6 @@ const { getEsriTypeFromDefinition, - getEsriTypeFromValue + getEsriTypeFromValue, } = require('./esri-type-utils'); const { ESRI_FIELD_TYPE_OID, @@ -10,21 +10,21 @@ const { SQL_TYPE_INTEGER, SQL_TYPE_OTHER, SQL_TYPE_FLOAT, - OBJECTID_DEFAULT_KEY + OBJECTID_DEFAULT_KEY, } = require('./constants'); class Field { - setEditable (value = false) { + setEditable(value = false) { this.editable = value; return this; } - setNullable (value = false) { + setNullable(value = false) { this.nullable = value; return this; } - setLength () { + setLength() { if (this.type === ESRI_FIELD_TYPE_STRING) { this.length = 128; } else if (this.type === ESRI_FIELD_TYPE_DATE) { @@ -34,7 +34,7 @@ class Field { } class ObjectIdField extends Field { - constructor (key = OBJECTID_DEFAULT_KEY) { + constructor(key = OBJECTID_DEFAULT_KEY) { super(); this.name = key; this.type = ESRI_FIELD_TYPE_OID; @@ -46,7 +46,7 @@ class ObjectIdField extends Field { } class FieldFromKeyValue extends Field { - constructor (key, value) { + constructor(key, value) { super(); this.name = key; this.type = getEsriTypeFromValue(value); @@ -59,7 +59,7 @@ class FieldFromKeyValue extends Field { } class StatisticField extends Field { - constructor (key) { + constructor(key) { super(); this.name = key; this.type = ESRI_FIELD_TYPE_DOUBLE; @@ -71,7 +71,7 @@ class StatisticField extends Field { } class StatisticDateField extends StatisticField { - constructor (key) { + constructor(key) { super(key); this.type = ESRI_FIELD_TYPE_DATE; this.sqlType = SQL_TYPE_OTHER; @@ -79,17 +79,10 @@ class StatisticDateField extends StatisticField { } class FieldFromFieldDefinition extends Field { - constructor (fieldDefinition) { + constructor(fieldDefinition) { super(); - const { - name, - type, - alias, - domain, - sqlType, - length, - defaultValue - } = fieldDefinition; + const { name, type, alias, domain, sqlType, length, defaultValue } = + fieldDefinition; this.name = name; this.type = getEsriTypeFromDefinition(type); @@ -106,7 +99,7 @@ class FieldFromFieldDefinition extends Field { } class ObjectIdFieldFromDefinition extends FieldFromFieldDefinition { - constructor (definition = {}) { + constructor(definition = {}) { super(definition); this.type = ESRI_FIELD_TYPE_OID; this.sqlType = SQL_TYPE_INTEGER; @@ -120,5 +113,5 @@ module.exports = { FieldFromKeyValue, FieldFromFieldDefinition, StatisticField, - StatisticDateField + StatisticDateField, }; diff --git a/packages/featureserver/src/helpers/fields/field-classes.spec.js b/packages/featureserver/src/helpers/fields/field-classes.spec.js index 3c8c60427..cd55237ed 100644 --- a/packages/featureserver/src/helpers/fields/field-classes.spec.js +++ b/packages/featureserver/src/helpers/fields/field-classes.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const { FieldFromKeyValue, @@ -6,7 +6,7 @@ const { FieldFromFieldDefinition, ObjectIdFieldFromDefinition, StatisticField, - StatisticDateField + StatisticDateField, } = require('./field-classes'); describe('FieldFromKeyValue', () => { @@ -19,7 +19,7 @@ describe('FieldFromKeyValue', () => { sqlType: 'sqlTypeOther', length: 128, domain: null, - defaultValue: null + defaultValue: null, }); result.setEditable().setNullable(); @@ -32,7 +32,7 @@ describe('FieldFromKeyValue', () => { domain: null, defaultValue: null, editable: false, - nullable: false + nullable: false, }); result.setEditable(true).setNullable(true); @@ -45,7 +45,7 @@ describe('FieldFromKeyValue', () => { domain: null, defaultValue: null, editable: true, - nullable: true + nullable: true, }); }); }); @@ -59,7 +59,7 @@ describe('ObjectIdField', () => { type: 'esriFieldTypeOID', sqlType: 'sqlTypeInteger', domain: null, - defaultValue: null + defaultValue: null, }); result.setEditable().setNullable(); @@ -71,7 +71,7 @@ describe('ObjectIdField', () => { domain: null, defaultValue: null, editable: false, - nullable: false + nullable: false, }); result.setEditable(true).setNullable(true); @@ -83,7 +83,7 @@ describe('ObjectIdField', () => { domain: null, defaultValue: null, editable: true, - nullable: true + nullable: true, }); }); }); @@ -92,7 +92,7 @@ describe('FieldFromFieldDefinition', () => { it('should produce expected instance from name, type definitions', () => { const result = new FieldFromFieldDefinition({ name: 'foo', - type: 'String' + type: 'String', }); result.should.deepEqual({ name: 'foo', @@ -101,7 +101,7 @@ describe('FieldFromFieldDefinition', () => { sqlType: 'sqlTypeOther', length: 128, domain: null, - defaultValue: null + defaultValue: null, }); result.setEditable().setNullable(); @@ -114,7 +114,7 @@ describe('FieldFromFieldDefinition', () => { domain: null, defaultValue: null, editable: false, - nullable: false + nullable: false, }); result.setEditable(true).setNullable(true); @@ -127,7 +127,7 @@ describe('FieldFromFieldDefinition', () => { domain: null, defaultValue: null, editable: true, - nullable: true + nullable: true, }); }); @@ -138,7 +138,7 @@ describe('FieldFromFieldDefinition', () => { alias: 'foolish', domain: 'domain-value', defaultValue: 'default-value', - length: 256 + length: 256, }); result.should.deepEqual({ name: 'foo', @@ -147,7 +147,7 @@ describe('FieldFromFieldDefinition', () => { sqlType: 'sqlTypeOther', domain: 'domain-value', defaultValue: 'default-value', - length: 256 + length: 256, }); }); }); @@ -158,7 +158,7 @@ describe('ObjectIdFieldFromFieldDefinition', () => { name: 'foo', type: 'String', editable: true, - nullable: true + nullable: true, }); result.should.deepEqual({ name: 'foo', @@ -166,7 +166,7 @@ describe('ObjectIdFieldFromFieldDefinition', () => { type: 'esriFieldTypeOID', sqlType: 'sqlTypeInteger', domain: null, - defaultValue: null + defaultValue: null, }); result.setEditable().setNullable(); @@ -178,7 +178,7 @@ describe('ObjectIdFieldFromFieldDefinition', () => { domain: null, defaultValue: null, editable: false, - nullable: false + nullable: false, }); result.setEditable(true).setNullable(true); @@ -190,7 +190,7 @@ describe('ObjectIdFieldFromFieldDefinition', () => { domain: null, defaultValue: null, editable: true, - nullable: true + nullable: true, }); }); }); @@ -204,7 +204,7 @@ describe('StatisticsField', () => { type: 'esriFieldTypeDouble', sqlType: 'sqlTypeFloat', domain: null, - defaultValue: null + defaultValue: null, }); }); }); @@ -218,7 +218,7 @@ describe('StatisticsDateField', () => { type: 'esriFieldTypeDate', sqlType: 'sqlTypeOther', domain: null, - defaultValue: null + defaultValue: null, }); }); }); diff --git a/packages/featureserver/src/helpers/fields/fields.js b/packages/featureserver/src/helpers/fields/fields.js index 6f43e3f57..361d254af 100644 --- a/packages/featureserver/src/helpers/fields/fields.js +++ b/packages/featureserver/src/helpers/fields/fields.js @@ -3,18 +3,15 @@ const { ObjectIdField, FieldFromKeyValue, FieldFromFieldDefinition, - ObjectIdFieldFromDefinition + ObjectIdFieldFromDefinition, } = require('./field-classes'); const logManager = require('../../log-manager'); class Fields { - static normalizeOptions (inputOptions) { + static normalizeOptions(inputOptions) { const { features, - metadata: { - fields, - idField - } = {}, + metadata: { fields, idField } = {}, attributeSample, ...options } = inputOptions; @@ -22,20 +19,19 @@ class Fields { return { idField: options.idField || idField, fieldDefinitions: options.fieldDefinitions || options.fields || fields, - attributeSample: attributeSample || getAttributeSample(features, attributeSample), - ...options + attributeSample: + attributeSample || getAttributeSample(features, attributeSample), + ...options, }; } - constructor (options = {}) { - const { - fieldDefinitions, - idField, - attributeSample = {} - } = options; + constructor(options = {}) { + const { fieldDefinitions, idField, attributeSample = {} } = options; if (shouldWarnAboutMissingIdFieldDefinition(idField, fieldDefinitions)) { - logManager.logger.debug(`provider's "idField" is set to ${idField}, but this field is not found in field-definitions`); + logManager.logger.debug( + `provider's "idField" is set to ${idField}, but this field is not found in field-definitions`, + ); } const normalizedIdField = idField || 'OBJECTID'; @@ -46,24 +42,26 @@ class Fields { } } -function getAttributeSample (features) { - return _.get(features, '[0].properties') || _.get(features, '[0].attributes', {}); +function getAttributeSample(features) { + return ( + _.get(features, '[0].properties') || _.get(features, '[0].attributes', {}) + ); } -function shouldWarnAboutMissingIdFieldDefinition (idField, fieldDefinitions) { +function shouldWarnAboutMissingIdFieldDefinition(idField, fieldDefinitions) { if (!idField || !fieldDefinitions) { return; } - const fieldNames = fieldDefinitions.map(field => field.name); + const fieldNames = fieldDefinitions.map((field) => field.name); return !fieldNames.includes(idField); } -function setFieldsFromDefinitions (fieldDefinitions, idField) { +function setFieldsFromDefinitions(fieldDefinitions, idField) { const fields = fieldDefinitions - .filter(fieldDefinition => fieldDefinition.name !== idField) - .map(fieldDefinition => { + .filter((fieldDefinition) => fieldDefinition.name !== idField) + .map((fieldDefinition) => { return new FieldFromFieldDefinition(fieldDefinition); }); @@ -72,9 +70,9 @@ function setFieldsFromDefinitions (fieldDefinitions, idField) { return fields; } -function setFieldsFromProperties (propertiesSample, idField) { +function setFieldsFromProperties(propertiesSample, idField) { const fieldNames = Object.keys(propertiesSample); - const simpleFieldNames = fieldNames.filter(name => name !== idField); + const simpleFieldNames = fieldNames.filter((name) => name !== idField); const fields = simpleFieldNames.map((key) => { return new FieldFromKeyValue(key, propertiesSample[key]); @@ -85,8 +83,8 @@ function setFieldsFromProperties (propertiesSample, idField) { return fields; } -function getIdFieldDefinition (fieldDefinitions, idField) { - const idFieldDefinition = fieldDefinitions.find(definition => { +function getIdFieldDefinition(fieldDefinitions, idField) { + const idFieldDefinition = fieldDefinitions.find((definition) => { return definition.name === idField; }); diff --git a/packages/featureserver/src/helpers/fields/fields.spec.js b/packages/featureserver/src/helpers/fields/fields.spec.js index 6342dce37..2c42193ee 100644 --- a/packages/featureserver/src/helpers/fields/fields.spec.js +++ b/packages/featureserver/src/helpers/fields/fields.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const Fields = require('./fields'); @@ -9,8 +9,8 @@ describe('Fields', () => { fieldDefinitions: 'foo', fields: 'bar', metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('foo'); @@ -20,8 +20,8 @@ describe('Fields', () => { const { fieldDefinitions } = Fields.normalizeOptions({ fields: 'bar', metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('bar'); @@ -30,8 +30,8 @@ describe('Fields', () => { it('should use "metadata.fields" when supplied', () => { const { fieldDefinitions } = Fields.normalizeOptions({ metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('snafu'); @@ -41,8 +41,8 @@ describe('Fields', () => { const { idField } = Fields.normalizeOptions({ idField: 'bar', metadata: { - idField: 'snafu' - } + idField: 'snafu', + }, }); idField.should.equal('bar'); @@ -51,8 +51,8 @@ describe('Fields', () => { it('should use "metadata.idField" when supplied', () => { const { idField } = Fields.normalizeOptions({ metadata: { - idField: 'snafu' - } + idField: 'snafu', + }, }); idField.should.equal('snafu'); @@ -60,7 +60,7 @@ describe('Fields', () => { it('should defer to root-level "attributeSample" when supplied', () => { const { attributeSample } = Fields.normalizeOptions({ - attributeSample: 'bar' + attributeSample: 'bar', }); attributeSample.should.equal('bar'); @@ -70,8 +70,8 @@ describe('Fields', () => { const { attributeSample } = Fields.normalizeOptions({ features: [ { attributes: { name: 'foo' } }, - { attributes: { name: 'bar' } } - ] + { attributes: { name: 'bar' } }, + ], }); attributeSample.should.deepEqual({ name: 'foo' }); @@ -81,8 +81,8 @@ describe('Fields', () => { const { attributeSample } = Fields.normalizeOptions({ features: [ { properties: { name: 'foo' } }, - { properties: { name: 'bar' } } - ] + { properties: { name: 'bar' } }, + ], }); attributeSample.should.deepEqual({ name: 'foo' }); @@ -90,7 +90,7 @@ describe('Fields', () => { it('should have "attributeSample" default to empty object', () => { const { attributeSample } = Fields.normalizeOptions({ - features: [] + features: [], }); attributeSample.should.deepEqual({}); @@ -100,28 +100,29 @@ describe('Fields', () => { describe('constructor', () => { it('should set fields from definitions, add OBJECTID', () => { const fields = new Fields({ - fieldDefinitions: [ - { name: 'foo', type: 'String' } - ] + fieldDefinitions: [{ name: 'foo', type: 'String' }], }); fields.should.deepEqual({ - fields: [{ - name: 'OBJECTID', - type: 'esriFieldTypeOID', - alias: 'OBJECTID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'OBJECTID', + type: 'esriFieldTypeOID', + alias: 'OBJECTID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); @@ -129,27 +130,30 @@ describe('Fields', () => { const fields = new Fields({ fieldDefinitions: [ { name: 'foo', type: 'String' }, - { name: 'OBJECTID', type: 'Integer' } - ] + { name: 'OBJECTID', type: 'Integer' }, + ], }); fields.should.deepEqual({ - fields: [{ - name: 'OBJECTID', - type: 'esriFieldTypeOID', - alias: 'OBJECTID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'OBJECTID', + type: 'esriFieldTypeOID', + alias: 'OBJECTID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); @@ -158,103 +162,115 @@ describe('Fields', () => { idField: 'bar', fieldDefinitions: [ { name: 'foo', type: 'String' }, - { name: 'bar', type: 'Integer' } - ] + { name: 'bar', type: 'Integer' }, + ], }); fields.should.deepEqual({ - fields: [{ - name: 'bar', - type: 'esriFieldTypeOID', - alias: 'bar', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'bar', + type: 'esriFieldTypeOID', + alias: 'bar', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); it('should set fields from attributeSample, add OBJECTID', () => { const fields = new Fields({ - attributeSample: { foo: 'bar' } + attributeSample: { foo: 'bar' }, }); fields.should.deepEqual({ - fields: [{ - name: 'OBJECTID', - type: 'esriFieldTypeOID', - alias: 'OBJECTID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'OBJECTID', + type: 'esriFieldTypeOID', + alias: 'OBJECTID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); it('should set fields from attributeSample, use included OBJECTID', () => { const fields = new Fields({ - attributeSample: { OBJECTID: 1234, foo: 'bar' } + attributeSample: { OBJECTID: 1234, foo: 'bar' }, }); fields.should.deepEqual({ - fields: [{ - name: 'OBJECTID', - type: 'esriFieldTypeOID', - alias: 'OBJECTID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'OBJECTID', + type: 'esriFieldTypeOID', + alias: 'OBJECTID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); it('should set fields from attributeSample, use included OBJECTID', () => { const fields = new Fields({ idField: 'hello', - attributeSample: { hello: 1234, foo: 'bar' } + attributeSample: { hello: 1234, foo: 'bar' }, }); fields.should.deepEqual({ - fields: [{ - name: 'hello', - type: 'esriFieldTypeOID', - alias: 'hello', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - type: 'esriFieldTypeString', - alias: 'foo', - sqlType: 'sqlTypeOther', - domain: null, - defaultValue: null, - length: 128 - }] + fields: [ + { + name: 'hello', + type: 'esriFieldTypeOID', + alias: 'hello', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + type: 'esriFieldTypeString', + alias: 'foo', + sqlType: 'sqlTypeOther', + domain: null, + defaultValue: null, + length: 128, + }, + ], }); }); }); diff --git a/packages/featureserver/src/helpers/fields/index.js b/packages/featureserver/src/helpers/fields/index.js index 097f0693c..ecf5283d7 100644 --- a/packages/featureserver/src/helpers/fields/index.js +++ b/packages/featureserver/src/helpers/fields/index.js @@ -5,5 +5,5 @@ const LayerFields = require('./layer-fields'); module.exports = { QueryFields, StatisticsFields, - LayerFields + LayerFields, }; diff --git a/packages/featureserver/src/helpers/fields/layer-fields.js b/packages/featureserver/src/helpers/fields/layer-fields.js index e768752af..27f85392c 100644 --- a/packages/featureserver/src/helpers/fields/layer-fields.js +++ b/packages/featureserver/src/helpers/fields/layer-fields.js @@ -1,25 +1,30 @@ const Fields = require('./fields'); class LayerFields extends Fields { - static create (inputOptions) { + static create(inputOptions) { const options = Fields.normalizeOptions(inputOptions); return new LayerFields(options); } - constructor (options) { + constructor(options) { super(options); - return this.fields.map(field => { - const { editable = false, nullable = false } = findDefinition(field.name, options.fieldDefinitions); + return this.fields.map((field) => { + const { editable = false, nullable = false } = findDefinition( + field.name, + options.fieldDefinitions, + ); field.setEditable(editable).setNullable(nullable); return field; }); } } -function findDefinition (fieldName, fieldDefinitions = []) { - return fieldDefinitions.find(definition => { - return definition.name === fieldName; - }) || {}; +function findDefinition(fieldName, fieldDefinitions = []) { + return ( + fieldDefinitions.find((definition) => { + return definition.name === fieldName; + }) || {} + ); } module.exports = LayerFields; diff --git a/packages/featureserver/src/helpers/fields/layer-fields.spec.js b/packages/featureserver/src/helpers/fields/layer-fields.spec.js index 651744421..121f7a9be 100644 --- a/packages/featureserver/src/helpers/fields/layer-fields.spec.js +++ b/packages/featureserver/src/helpers/fields/layer-fields.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const LayerFields = require('./layer-fields'); @@ -7,268 +7,301 @@ describe('LayerFields', () => { const result = LayerFields.create({ fields: [ { name: 'foo', type: 'String' }, - { name: 'bar', type: 'String', editable: true, nullable: true } - ] + { name: 'bar', type: 'String', editable: true, nullable: true }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'bar', - alias: 'bar', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: true, - nullable: true - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'bar', + alias: 'bar', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: true, + nullable: true, + }, + ]); }); it('create fields from definitions, assign idField as OBJECTID', () => { const result = LayerFields.create({ - fields: [ - { name: 'foo', type: 'Integer' } - ], - idField: 'foo' + fields: [{ name: 'foo', type: 'Integer' }], + idField: 'foo', }); - result.should.deepEqual([{ - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from attributes sample, adds OBJECTID', () => { const result = LayerFields.create({ attributeSample: { - foo: 'bar' - } + foo: 'bar', + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from attributes sample, finds and uses OBJECTID', () => { const result = LayerFields.create({ attributeSample: { foo: 'bar', - OBJECTID: 1 - } + OBJECTID: 1, + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from attributes sample, adds OBJECTID', () => { const result = LayerFields.create({ attributeSample: { - foo: 'bar' - } + foo: 'bar', + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from geojson data, adds OBJECTID', () => { const result = LayerFields.create({ - features: [{ - properties: { - foo: 'bar' - } - }] + features: [ + { + properties: { + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from geojson data, finds and uses OBJECTID', () => { const result = LayerFields.create({ - features: [{ - properties: { - OBJECTID: 1, - foo: 'bar' - } - }] + features: [ + { + properties: { + OBJECTID: 1, + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from esri json data, adds OBJECTID', () => { const result = LayerFields.create({ - features: [{ - attributes: { - foo: 'bar' - } - }] + features: [ + { + attributes: { + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); it('create fields from esri json data, finds and uses OBJECTID', () => { const result = LayerFields.create({ - features: [{ - attributes: { - OBJECTID: 1, - foo: 'bar' - } - }] + features: [ + { + attributes: { + OBJECTID: 1, + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null, - editable: false, - nullable: false - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null, - editable: false, - nullable: false - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + editable: false, + nullable: false, + }, + ]); }); }); diff --git a/packages/featureserver/src/helpers/fields/query-fields.js b/packages/featureserver/src/helpers/fields/query-fields.js index b7dbee65b..191ec756d 100644 --- a/packages/featureserver/src/helpers/fields/query-fields.js +++ b/packages/featureserver/src/helpers/fields/query-fields.js @@ -1,17 +1,15 @@ const Fields = require('./fields'); class QueryFields extends Fields { - static create (inputOptions = {}) { + static create(inputOptions = {}) { const options = Fields.normalizeOptions(inputOptions); return new QueryFields(options); } - constructor (options = {}) { + constructor(options = {}) { super(options); - const { - outFields - } = options; + const { outFields } = options; if (outFields && outFields !== '*') { return filterByOutfields(outFields, this.fields); @@ -21,9 +19,9 @@ class QueryFields extends Fields { } } -function filterByOutfields (outFields, fields) { - const outFieldNames = outFields.split(/\s*,\s*/); - return fields.filter(field => { +function filterByOutfields(outFields, fields) { + const outFieldNames = outFields.split(',').map((field) => field.trim()); + return fields.filter((field) => { return outFieldNames.includes(field.name); }); } diff --git a/packages/featureserver/src/helpers/fields/query-fields.spec.js b/packages/featureserver/src/helpers/fields/query-fields.spec.js index 6f6ad3ced..5cc114124 100644 --- a/packages/featureserver/src/helpers/fields/query-fields.spec.js +++ b/packages/featureserver/src/helpers/fields/query-fields.spec.js @@ -1,230 +1,260 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const QueryFields = require('./query-fields'); describe('QueryFields', () => { it('create fields from definitions, adds OBJECTID', () => { const result = QueryFields.create({ - fields: [ - { name: 'foo', type: 'String' } - ] + fields: [{ name: 'foo', type: 'String' }], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from definitions, assign idField as OBJECTID', () => { const result = QueryFields.create({ - fields: [ - { name: 'foo', type: 'Integer' } - ], - idField: 'foo' + fields: [{ name: 'foo', type: 'Integer' }], + idField: 'foo', }); - result.should.deepEqual([{ - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from attributes sample, adds OBJECTID', () => { const result = QueryFields.create({ attributeSample: { - foo: 'bar' - } + foo: 'bar', + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from attributes sample, finds and uses OBJECTID', () => { const result = QueryFields.create({ attributeSample: { foo: 'bar', - OBJECTID: 1 - } + OBJECTID: 1, + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from attributes sample, adds OBJECTID', () => { const result = QueryFields.create({ attributeSample: { - foo: 'bar' - } + foo: 'bar', + }, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from geojson data, adds OBJECTID', () => { const result = QueryFields.create({ - features: [{ - properties: { - foo: 'bar' - } - }] + features: [ + { + properties: { + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from geojson data, finds and uses OBJECTID', () => { const result = QueryFields.create({ - features: [{ - properties: { - OBJECTID: 1, - foo: 'bar' - } - }] + features: [ + { + properties: { + OBJECTID: 1, + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from esri json data, adds OBJECTID', () => { const result = QueryFields.create({ - features: [{ - attributes: { - foo: 'bar' - } - }] + features: [ + { + attributes: { + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('create fields from esri json data, finds and uses OBJECTID', () => { const result = QueryFields.create({ - features: [{ - attributes: { - OBJECTID: 1, - foo: 'bar' - } - }] + features: [ + { + attributes: { + OBJECTID: 1, + foo: 'bar', + }, + }, + ], }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('outFields option filters fields array', () => { @@ -232,128 +262,143 @@ describe('QueryFields', () => { fields: [ { name: 'foo', type: 'String' }, { name: 'bar', type: 'String' }, - { name: 'hello', type: 'String' } + { name: 'hello', type: 'String' }, ], - outFields: 'foo,hello' + outFields: 'foo, hello', }); - result.should.deepEqual([{ - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }, { - name: 'hello', - alias: 'hello', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + { + name: 'hello', + alias: 'hello', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('outFields wildcard does not filter fields array', () => { const result = QueryFields.create({ fields: [ { name: 'foo', type: 'String' }, - { name: 'hello', type: 'String' } + { name: 'hello', type: 'String' }, ], - outFields: '*' + outFields: '*', }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }, { - name: 'hello', - alias: 'hello', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + { + name: 'hello', + alias: 'hello', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('outFields empty string does not filter fields array', () => { const result = QueryFields.create({ fields: [ { name: 'foo', type: 'String' }, - { name: 'hello', type: 'String' } + { name: 'hello', type: 'String' }, ], - outFields: '' + outFields: '', }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }, { - name: 'hello', - alias: 'hello', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + { + name: 'hello', + alias: 'hello', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); it('outFields null value does not filter fields array', () => { const result = QueryFields.create({ fields: [ { name: 'foo', type: 'String' }, - { name: 'hello', type: 'String' } + { name: 'hello', type: 'String' }, ], - outFields: null + outFields: null, }); - result.should.deepEqual([{ - name: 'OBJECTID', - alias: 'OBJECTID', - type: 'esriFieldTypeOID', - sqlType: 'sqlTypeInteger', - domain: null, - defaultValue: null - }, { - name: 'foo', - alias: 'foo', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }, { - name: 'hello', - alias: 'hello', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'OBJECTID', + alias: 'OBJECTID', + type: 'esriFieldTypeOID', + sqlType: 'sqlTypeInteger', + domain: null, + defaultValue: null, + }, + { + name: 'foo', + alias: 'foo', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + { + name: 'hello', + alias: 'hello', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + domain: null, + defaultValue: null, + }, + ]); }); }); diff --git a/packages/featureserver/src/helpers/fields/statistics-fields.js b/packages/featureserver/src/helpers/fields/statistics-fields.js index e19fc7e8b..4a3381782 100644 --- a/packages/featureserver/src/helpers/fields/statistics-fields.js +++ b/packages/featureserver/src/helpers/fields/statistics-fields.js @@ -5,94 +5,92 @@ const { StatisticField, StatisticDateField, FieldFromFieldDefinition, - FieldFromKeyValue + FieldFromKeyValue, } = require('./field-classes'); class StatisticsFields { - static normalizeOptions (inputOptions = {}) { + static normalizeOptions(inputOptions = {}) { const { statistics, - metadata: { - fields - } = {}, + metadata: { fields } = {}, groupByFieldsForStatistics = [], attributeSample, ...options } = inputOptions; - return { statisticsSample: Array.isArray(statistics) ? statistics[0] : statistics, fieldDefinitions: options.fieldDefinitions || options.fields || fields, groupByFieldsForStatistics: getGroupByFields(groupByFieldsForStatistics), - ...options + ...options, }; } - static create (inputOptions) { + static create(inputOptions) { const options = StatisticsFields.normalizeOptions(inputOptions); return new StatisticsFields(options); } - constructor (options = {}) { + constructor(options = {}) { const { statisticsSample, groupByFieldsForStatistics = [], fieldDefinitions = [], - outStatistics + outStatistics, } = options; const dateFieldRegexs = getDateFieldRegexs(fieldDefinitions, outStatistics); - this.fields = Object - .entries(statisticsSample) - .map(([key, value]) => { - if (groupByFieldsForStatistics.includes(key)) { - const fieldDefinition = fieldDefinitions.find(({ name }) => name === key); - - if (fieldDefinition) { - return new FieldFromFieldDefinition(fieldDefinition); - } + this.fields = Object.entries(statisticsSample).map(([key, value]) => { + if (groupByFieldsForStatistics.includes(key)) { + const fieldDefinition = fieldDefinitions.find( + ({ name }) => name === key, + ); - return new FieldFromKeyValue(key, value); + if (fieldDefinition) { + return new FieldFromFieldDefinition(fieldDefinition); } - if (isDateField(dateFieldRegexs, key, value)) { - return new StatisticDateField(key); - } + return new FieldFromKeyValue(key, value); + } + + if (isDateField(dateFieldRegexs, key, value)) { + return new StatisticDateField(key); + } - return new StatisticField(key); - }); + return new StatisticField(key); + }); return this.fields; } } -function getGroupByFields (inputVal) { +function getGroupByFields(inputVal) { if (Array.isArray(inputVal)) { return inputVal; } - return inputVal.split(',').map(str => str.trim()); + return inputVal.split(',').map((str) => str.trim()); } -function isDateField (regexs, fieldName, value) { - return regexs.some(regex => { - return regex.test(fieldName); - }) || isDate(value); +function isDateField(regexs, fieldName, value) { + return ( + regexs.some((regex) => { + return regex.test(fieldName); + }) || isDate(value) + ); } -function getDateFieldRegexs (fieldDefinitions = [], outStatistics = []) { - const dateFields = fieldDefinitions.filter(({ type }) => { - return getEsriTypeFromDefinition(type) === ESRI_FIELD_TYPE_DATE; - }).map(({ name }) => name); +function getDateFieldRegexs(fieldDefinitions = [], outStatistics = []) { + const dateFields = fieldDefinitions + .filter(({ type }) => { + return getEsriTypeFromDefinition(type) === ESRI_FIELD_TYPE_DATE; + }) + .map(({ name }) => name); return outStatistics .filter(({ onStatisticField }) => dateFields.includes(onStatisticField)) .map((statistic) => { - const { - onStatisticField, - outStatisticFieldName - } = statistic; + const { onStatisticField, outStatisticFieldName } = statistic; const name = outStatisticFieldName || onStatisticField; const spaceEscapedName = name.replace(/\s/g, '_'); diff --git a/packages/featureserver/src/helpers/fields/statistics-fields.spec.js b/packages/featureserver/src/helpers/fields/statistics-fields.spec.js index 124b2689a..4d6c8d503 100644 --- a/packages/featureserver/src/helpers/fields/statistics-fields.spec.js +++ b/packages/featureserver/src/helpers/fields/statistics-fields.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const StatisticsFields = require('./statistics-fields'); @@ -6,7 +6,7 @@ describe('StatisticsFields', () => { describe('static normalizeOptions method', () => { it('should use first element of statistics array as sample', () => { const { statisticsSample } = StatisticsFields.normalizeOptions({ - statistics: [{ foo: '1.234' }] + statistics: [{ foo: '1.234' }], }); statisticsSample.should.deepEqual({ foo: '1.234' }); @@ -14,7 +14,7 @@ describe('StatisticsFields', () => { it('should use statistics object as sample', () => { const { statisticsSample } = StatisticsFields.normalizeOptions({ - statistics: { foo: '1.234' } + statistics: { foo: '1.234' }, }); statisticsSample.should.deepEqual({ foo: '1.234' }); }); @@ -24,8 +24,8 @@ describe('StatisticsFields', () => { fieldDefinitions: 'foo', fields: 'bar', metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('foo'); @@ -35,8 +35,8 @@ describe('StatisticsFields', () => { const { fieldDefinitions } = StatisticsFields.normalizeOptions({ fields: 'bar', metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('bar'); @@ -45,8 +45,8 @@ describe('StatisticsFields', () => { it('should use "metadata.fields" when supplied', () => { const { fieldDefinitions } = StatisticsFields.normalizeOptions({ metadata: { - fields: 'snafu' - } + fields: 'snafu', + }, }); fieldDefinitions.should.equal('snafu'); @@ -54,7 +54,7 @@ describe('StatisticsFields', () => { it('should convert groupByFieldsForStatistics string to array and remove whitespace', () => { const { groupByFieldsForStatistics } = StatisticsFields.normalizeOptions({ - groupByFieldsForStatistics: 'hello, world , today ' + groupByFieldsForStatistics: 'hello, world , today ', }); groupByFieldsForStatistics.should.deepEqual(['hello', 'world', 'today']); @@ -62,14 +62,16 @@ describe('StatisticsFields', () => { it('should use groupByFieldsForStatistics array', () => { const { groupByFieldsForStatistics } = StatisticsFields.normalizeOptions({ - groupByFieldsForStatistics: ['hello'] + groupByFieldsForStatistics: ['hello'], }); groupByFieldsForStatistics.should.deepEqual(['hello']); }); it('should default groupByFieldsForStatistics to empty array', () => { - const { groupByFieldsForStatistics } = StatisticsFields.normalizeOptions({}); + const { groupByFieldsForStatistics } = StatisticsFields.normalizeOptions( + {}, + ); groupByFieldsForStatistics.should.deepEqual([]); }); @@ -78,62 +80,72 @@ describe('StatisticsFields', () => { describe('static create method', () => { it('should create fields from statistics and without definitions', () => { const result = StatisticsFields.create({ - statisticsSample: { foo: 1.234 } + statisticsSample: { foo: 1.234 }, }); - result.should.deepEqual([{ - name: 'foo', - type: 'esriFieldTypeDouble', - sqlType: 'sqlTypeFloat', - alias: 'foo', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + type: 'esriFieldTypeDouble', + sqlType: 'sqlTypeFloat', + alias: 'foo', + domain: null, + defaultValue: null, + }, + ]); }); it('should create date field when value is ISO-string date', () => { const result = StatisticsFields.create({ - statisticsSample: { foo: new Date().toISOString() } + statisticsSample: { foo: new Date().toISOString() }, }); - result.should.deepEqual([{ - name: 'foo', - type: 'esriFieldTypeDate', - sqlType: 'sqlTypeOther', - alias: 'foo', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + type: 'esriFieldTypeDate', + sqlType: 'sqlTypeOther', + alias: 'foo', + domain: null, + defaultValue: null, + }, + ]); }); it('should create date field when field is defined as date', () => { const result = StatisticsFields.create({ statisticsSample: { foo: 100000 }, fieldDefinitions: [{ name: 'foo', type: 'Date' }], - outStatistics: [{ onStatisticField: 'foo' }] + outStatistics: [{ onStatisticField: 'foo' }], }); - result.should.deepEqual([{ - name: 'foo', - type: 'esriFieldTypeDate', - sqlType: 'sqlTypeOther', - alias: 'foo', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + type: 'esriFieldTypeDate', + sqlType: 'sqlTypeOther', + alias: 'foo', + domain: null, + defaultValue: null, + }, + ]); }); it('should create date field when field is defined as date, but custom label requested', () => { const result = StatisticsFields.create({ statisticsSample: { bar: 100000 }, fieldDefinitions: [{ name: 'foo', type: 'Date' }], - outStatistics: [{ onStatisticField: 'foo', outStatisticFieldName: 'bar' }] + outStatistics: [ + { onStatisticField: 'foo', outStatisticFieldName: 'bar' }, + ], }); - result.should.deepEqual([{ - name: 'bar', - type: 'esriFieldTypeDate', - sqlType: 'sqlTypeOther', - alias: 'bar', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'bar', + type: 'esriFieldTypeDate', + sqlType: 'sqlTypeOther', + alias: 'bar', + domain: null, + defaultValue: null, + }, + ]); }); it('should create date field and groupBy fields', () => { @@ -141,31 +153,35 @@ describe('StatisticsFields', () => { statisticsSample: { foo: 100000, bar: 'hello', walter: 1 }, fieldDefinitions: [{ name: 'foo', type: 'Date' }], outStatistics: [{ onStatisticField: 'foo' }], - groupByFieldsForStatistics: 'bar,walter' + groupByFieldsForStatistics: 'bar,walter', }); - result.should.deepEqual([{ - name: 'foo', - type: 'esriFieldTypeDate', - sqlType: 'sqlTypeOther', - alias: 'foo', - domain: null, - defaultValue: null - }, { - name: 'bar', - type: 'esriFieldTypeString', - sqlType: 'sqlTypeOther', - length: 128, - alias: 'bar', - domain: null, - defaultValue: null - }, { - name: 'walter', - type: 'esriFieldTypeInteger', - sqlType: 'sqlTypeOther', - alias: 'walter', - domain: null, - defaultValue: null - }]); + result.should.deepEqual([ + { + name: 'foo', + type: 'esriFieldTypeDate', + sqlType: 'sqlTypeOther', + alias: 'foo', + domain: null, + defaultValue: null, + }, + { + name: 'bar', + type: 'esriFieldTypeString', + sqlType: 'sqlTypeOther', + length: 128, + alias: 'bar', + domain: null, + defaultValue: null, + }, + { + name: 'walter', + type: 'esriFieldTypeInteger', + sqlType: 'sqlTypeOther', + alias: 'walter', + domain: null, + defaultValue: null, + }, + ]); }); }); }); diff --git a/packages/featureserver/src/helpers/get-collection-crs.js b/packages/featureserver/src/helpers/get-collection-crs.js index 2ce87ae85..56898d8ca 100644 --- a/packages/featureserver/src/helpers/get-collection-crs.js +++ b/packages/featureserver/src/helpers/get-collection-crs.js @@ -1,7 +1,7 @@ const _ = require('lodash'); const OGC_WGS84 = 'ogc:1.3:crs84'; -function getCollectionCrs (collection) { +function getCollectionCrs(collection) { const collectionCrs = _.get(collection, 'crs.properties.name'); if (!collectionCrs) return; @@ -15,7 +15,9 @@ function getCollectionCrs (collection) { if (!result) { return; } - const { groups: { srid } } = result; + const { + groups: { srid }, + } = result; return srid; } diff --git a/packages/featureserver/src/helpers/get-collection-crs.spec.js b/packages/featureserver/src/helpers/get-collection-crs.spec.js index 9946da128..58a787d99 100644 --- a/packages/featureserver/src/helpers/get-collection-crs.spec.js +++ b/packages/featureserver/src/helpers/get-collection-crs.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const getCollectionCrs = require('./get-collection-crs'); describe('get-collection-crs', () => { @@ -28,12 +28,16 @@ describe('get-collection-crs', () => { }); it('getCollectionCrs: WGS84 definition', () => { - const crs = getCollectionCrs({ crs: { properties: { name: 'urn:ogc:def:crs:ogc:1.3:crs84' } } }); + const crs = getCollectionCrs({ + crs: { properties: { name: 'urn:ogc:def:crs:ogc:1.3:crs84' } }, + }); should(crs).equal('4326'); }); it('getCollectionCrs: non-WGS84 definition', () => { - const crs = getCollectionCrs({ crs: { properties: { name: 'urn:ogc:def:crs:EPSG::2285' } } }); + const crs = getCollectionCrs({ + crs: { properties: { name: 'urn:ogc:def:crs:EPSG::2285' } }, + }); should(crs).equal('2285'); }); }); diff --git a/packages/featureserver/src/helpers/get-geometry-type-from-geojson.js b/packages/featureserver/src/helpers/get-geometry-type-from-geojson.js index b3a63d369..6d22494bf 100644 --- a/packages/featureserver/src/helpers/get-geometry-type-from-geojson.js +++ b/packages/featureserver/src/helpers/get-geometry-type-from-geojson.js @@ -11,11 +11,16 @@ const esriLookup = { esriGeometryPoint: 'esriGeometryPoint', esriGeometryMultipoint: 'esriGeometryMultipoint', esriGeometryPolyline: 'esriGeometryPolyline', - esriGeometryPolygon: 'esriGeometryPolygon' + esriGeometryPolygon: 'esriGeometryPolygon', }; -module.exports = function getGeometryTypeFromGeojson ({ geometryType, metadata = {}, features = [] } = {}) { - const type = geometryType || metadata.geometryType || findInFeatures(features); +module.exports = function getGeometryTypeFromGeojson({ + geometryType, + metadata = {}, + features = [], +} = {}) { + const type = + geometryType || metadata.geometryType || findInFeatures(features); if (!type) { logManager.logger.debug(`Input JSON has unsupported geometryType: ${type}`); @@ -23,8 +28,8 @@ module.exports = function getGeometryTypeFromGeojson ({ geometryType, metadata = return esriLookup[type]; }; -function findInFeatures (features) { - const featureWithGeometryType = features.find(feature => { +function findInFeatures(features) { + const featureWithGeometryType = features.find((feature) => { return _.get(feature, 'geometry.type'); }); diff --git a/packages/featureserver/src/helpers/get-geometry-type-from-geojson.spec.js b/packages/featureserver/src/helpers/get-geometry-type-from-geojson.spec.js index ce46657e0..75cc99548 100644 --- a/packages/featureserver/src/helpers/get-geometry-type-from-geojson.spec.js +++ b/packages/featureserver/src/helpers/get-geometry-type-from-geojson.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const { getGeometryTypeFromGeojson } = require('.'); describe('get-geometry-type-from-geojson', function () { @@ -18,27 +18,38 @@ describe('get-geometry-type-from-geojson', function () { }); it('defers to root-level geometryType', () => { - const result = getGeometryTypeFromGeojson({ geometryType: 'Point', metadata: { geometryType: 'foo' } }); + const result = getGeometryTypeFromGeojson({ + geometryType: 'Point', + metadata: { geometryType: 'foo' }, + }); result.should.equal('esriGeometryPoint'); }); it('uses metadata.geometryType when no root-level geometryType', () => { - const result = getGeometryTypeFromGeojson({ metadata: { geometryType: 'Point' } }); + const result = getGeometryTypeFromGeojson({ + metadata: { geometryType: 'Point' }, + }); result.should.equal('esriGeometryPoint'); }); it('uses feature geometry-type if no other source', () => { - const result = getGeometryTypeFromGeojson({ features: [{ geometry: { type: 'Point' } }] }); + const result = getGeometryTypeFromGeojson({ + features: [{ geometry: { type: 'Point' } }], + }); result.should.equal('esriGeometryPoint'); }); it('Searches for first feature geometry-type if no other source', () => { - const result = getGeometryTypeFromGeojson({ features: [{ geometry: null }, { geometry: { type: 'Point' } }] }); + const result = getGeometryTypeFromGeojson({ + features: [{ geometry: null }, { geometry: { type: 'Point' } }], + }); result.should.equal('esriGeometryPoint'); }); it('returns undefined feature geometry-type not defined', () => { - const result = getGeometryTypeFromGeojson({ features: [{ geometry: null }] }); + const result = getGeometryTypeFromGeojson({ + features: [{ geometry: null }], + }); should(result).equal(); }); @@ -49,7 +60,7 @@ describe('get-geometry-type-from-geojson', function () { LineString: 'esriGeometryPolyline', MultiLineString: 'esriGeometryPolyline', Polygon: 'esriGeometryPolygon', - MultiPolygon: 'esriGeometryPolygon' + MultiPolygon: 'esriGeometryPolygon', }; Object.entries(types).forEach(([key, value]) => { const result = getGeometryTypeFromGeojson({ geometryType: key }); diff --git a/packages/featureserver/src/helpers/get-spatial-reference.js b/packages/featureserver/src/helpers/get-spatial-reference.js index 34d080aa7..84ad4987f 100644 --- a/packages/featureserver/src/helpers/get-spatial-reference.js +++ b/packages/featureserver/src/helpers/get-spatial-reference.js @@ -2,9 +2,11 @@ const _ = require('lodash'); const getCollectionCrs = require('./get-collection-crs'); const normalizeSpatialReference = require('./normalize-spatial-reference'); -function getSpatialReference (geojson, { inputCrs, sourceSR } = {}) { +function getSpatialReference(geojson, { inputCrs, sourceSR } = {}) { if (!inputCrs && !sourceSR && _.isEmpty(geojson)) return; - const spatialReference = inputCrs || sourceSR || getCollectionCrs(geojson) || { wkid: 4326, latestWkid: 4326 }; + const spatialReference = inputCrs || + sourceSR || + getCollectionCrs(geojson) || { wkid: 4326, latestWkid: 4326 }; if (!spatialReference) return; diff --git a/packages/featureserver/src/helpers/get-spatial-reference.spec.js b/packages/featureserver/src/helpers/get-spatial-reference.spec.js index 8e347de18..2db8341f5 100644 --- a/packages/featureserver/src/helpers/get-spatial-reference.spec.js +++ b/packages/featureserver/src/helpers/get-spatial-reference.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const getSpatialReference = require('./get-spatial-reference'); describe('get-spatial-reference', () => { @@ -8,7 +8,9 @@ describe('get-spatial-reference', () => { }); it('getSpatialReference: only inputCrs', () => { - const wkt = getSpatialReference(undefined, { inputCrs: { wkid: 4326, latestWkid: 4326 } }); + const wkt = getSpatialReference(undefined, { + inputCrs: { wkid: 4326, latestWkid: 4326 }, + }); should(wkt).deepEqual({ wkid: 4326, latestWkid: 4326 }); }); @@ -28,12 +30,17 @@ describe('get-spatial-reference', () => { }); it('getSpatialReference: only geojson', () => { - const wkt = getSpatialReference({ crs: { properties: { name: 'epsg:3857' } } }); + const wkt = getSpatialReference({ + crs: { properties: { name: 'epsg:3857' } }, + }); should(wkt).deepEqual({ wkid: 3857, latestWkid: 3857 }); }); it('getSpatialReference: all inputs available', () => { - const wkt = getSpatialReference({ crs: { properties: { name: 'epsg:3857' } } }, { inputCrs: 4326, sourceSR: 102100 }); + const wkt = getSpatialReference( + { crs: { properties: { name: 'epsg:3857' } } }, + { inputCrs: 4326, sourceSR: 102100 }, + ); should(wkt).deepEqual({ wkid: 4326, latestWkid: 4326 }); }); }); diff --git a/packages/featureserver/src/helpers/index.js b/packages/featureserver/src/helpers/index.js index bda69c0b3..49b675830 100644 --- a/packages/featureserver/src/helpers/index.js +++ b/packages/featureserver/src/helpers/index.js @@ -8,8 +8,8 @@ module.exports = { getSpatialReference: require('./get-spatial-reference'), TableLayerMetadata: require('./table-layer-metadata'), FeatureLayerMetadata: require('./feature-layer-metadata'), - ...(require('./data-type-utils')), - ...(require('./renderers')), - ...(require('./validate-inputs')), - ...(require('./normalize-request-params')) + ...require('./data-type-utils'), + ...require('./renderers'), + ...require('./validate-inputs'), + ...require('./normalize-request-params'), }; diff --git a/packages/featureserver/src/helpers/is-geojson-table.js b/packages/featureserver/src/helpers/is-geojson-table.js index f8088f357..700bcca31 100644 --- a/packages/featureserver/src/helpers/is-geojson-table.js +++ b/packages/featureserver/src/helpers/is-geojson-table.js @@ -1,16 +1,23 @@ const _ = require('lodash'); const getGeometryTypeFromGeojson = require('./get-geometry-type-from-geojson'); -function hasValidFullExent (data) { +function hasValidFullExent(data) { // Check for a valid fullExtent. If unset, assume this is a Table - const fullExtent = data.fullExtent || (data.metadata && data.metadata.fullExtent); - if (_.isUndefined(fullExtent) || _.isUndefined(fullExtent.xmin) || _.isUndefined(fullExtent.ymin) || fullExtent.xmin === Infinity) return true; + const fullExtent = + data.fullExtent || (data.metadata && data.metadata.fullExtent); + if ( + _.isUndefined(fullExtent) || + _.isUndefined(fullExtent.xmin) || + _.isUndefined(fullExtent.ymin) || + fullExtent.xmin === Infinity + ) + return true; return false; } -module.exports = function isTable (data = {}) { -// geometry indicates this in not a table +module.exports = function isTable(data = {}) { + // geometry indicates this in not a table const geometryType = getGeometryTypeFromGeojson(data); if (geometryType) return false; diff --git a/packages/featureserver/src/helpers/is-geojson-table.spec.js b/packages/featureserver/src/helpers/is-geojson-table.spec.js index cd9f8212c..54b5d528d 100644 --- a/packages/featureserver/src/helpers/is-geojson-table.spec.js +++ b/packages/featureserver/src/helpers/is-geojson-table.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const isTable = require('./is-geojson-table'); describe('is-geojson-table', function () { @@ -13,20 +13,64 @@ describe('is-geojson-table', function () { }); it('GeoJSON collection input with geometry should return false', () => { - const collection = { type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [{ type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [-100, 40] } }, { type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [-101, 41] } }, { type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: [-99, 39] } }] }; + const collection = { + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [ + { + type: 'Feature', + properties: {}, + geometry: { type: 'Point', coordinates: [-100, 40] }, + }, + { + type: 'Feature', + properties: {}, + geometry: { type: 'Point', coordinates: [-101, 41] }, + }, + { + type: 'Feature', + properties: {}, + geometry: { type: 'Point', coordinates: [-99, 39] }, + }, + ], + }; const result = isTable(collection); should(result).be.exactly(false); }); it('GeoJSON collection input with NO geometry should return true', () => { - const collection = { type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [{ type: 'Feature', properties: {} }] }; + const collection = { + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [{ type: 'Feature', properties: {} }], + }; const result = isTable(collection); should(result).be.exactly(true); }); it('GeoJSON collection input with valid geometryType should return false', () => { - const collection = { type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [{ type: 'Feature', properties: {} }] }; - const geomTypes = ['Point', 'MultiPoint', 'LineString', 'MultiLineString', 'Polygon', 'MultiPolygon']; + const collection = { + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [{ type: 'Feature', properties: {} }], + }; + const geomTypes = [ + 'Point', + 'MultiPoint', + 'LineString', + 'MultiLineString', + 'Polygon', + 'MultiPolygon', + ]; geomTypes.forEach((geomType) => { collection.geometryType = geomType; const result = isTable(collection); @@ -35,7 +79,14 @@ describe('is-geojson-table', function () { }); it('GeoJSON collection input with INvalid geometryType should return true', () => { - const collection = { type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [{ type: 'Feature', properties: {} }] }; + const collection = { + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [{ type: 'Feature', properties: {} }], + }; const geomTypes = ['Other']; geomTypes.forEach((geomType) => { collection.geomType = geomType; @@ -45,13 +96,28 @@ describe('is-geojson-table', function () { }); it('GeoJSON collection input without features should return true', () => { - const collection = { type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [] }; + const collection = { + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [], + }; const result = isTable(collection); should(result).be.exactly(true); }); it('GeoJSON collection input with metadata geometryType but no features should return false', () => { - const collection = { metadata: { geometryType: 'Point' }, type: 'FeatureCollection', crs: { type: 'name', properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, features: [] }; + const collection = { + metadata: { geometryType: 'Point' }, + type: 'FeatureCollection', + crs: { + type: 'name', + properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' }, + }, + features: [], + }; const result = isTable(collection); should(result).be.exactly(false); }); diff --git a/packages/featureserver/src/helpers/normalize-extent.js b/packages/featureserver/src/helpers/normalize-extent.js index f0605be6d..734b97def 100644 --- a/packages/featureserver/src/helpers/normalize-extent.js +++ b/packages/featureserver/src/helpers/normalize-extent.js @@ -1,19 +1,27 @@ const joi = require('joi'); -const esriExtentSchema = joi.object({ - xmin: joi.number().required(), - xmax: joi.number().required(), - ymin: joi.number().required(), - ymax: joi.number().required(), - type: joi.string().optional(), - spatialReference: joi.object().keys({ - wkid: joi.number().integer().optional(), - latestWkid: joi.number().integer().optional() - }).optional() -}).unknown(); +const esriExtentSchema = joi + .object({ + xmin: joi.number().required(), + xmax: joi.number().required(), + ymin: joi.number().required(), + ymax: joi.number().required(), + type: joi.string().optional(), + spatialReference: joi + .object() + .keys({ + wkid: joi.number().integer().optional(), + latestWkid: joi.number().integer().optional(), + }) + .optional(), + }) + .unknown(); const simpleArraySchema = joi.array().items(joi.number().required()).min(4); -const cornerArraySchema = joi.array().items(joi.array().items(joi.number()).length(2)).length(2); +const cornerArraySchema = joi + .array() + .items(joi.array().items(joi.number()).length(2)) + .length(2); module.exports = function (input, spatialReference) { if (!input) return undefined; @@ -39,28 +47,28 @@ module.exports = function (input, spatialReference) { throw new Error(`Received invalid extent: ${JSON.stringify(input)}`); }; -function validate (input, schema) { +function validate(input, schema) { const { error, value } = schema.validate(input); if (error) return { error }; return { value }; } -function simpleArrayToEsriExtent (arrayExent, spatialReference) { +function simpleArrayToEsriExtent(arrayExent, spatialReference) { return { xmin: arrayExent[0], ymin: arrayExent[1], xmax: arrayExent[2], ymax: arrayExent[3], - spatialReference + spatialReference, }; } -function cornerArrayToEsriExtent (cornerArrayExtent, spatialReference) { +function cornerArrayToEsriExtent(cornerArrayExtent, spatialReference) { return { xmin: cornerArrayExtent[0][0], ymin: cornerArrayExtent[0][1], xmax: cornerArrayExtent[1][0], ymax: cornerArrayExtent[1][1], - spatialReference + spatialReference, }; } diff --git a/packages/featureserver/src/helpers/normalize-extent.spec.js b/packages/featureserver/src/helpers/normalize-extent.spec.js index 82031c3c9..329d9de4f 100644 --- a/packages/featureserver/src/helpers/normalize-extent.spec.js +++ b/packages/featureserver/src/helpers/normalize-extent.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const { normalizeExtent } = require('.'); describe('normalize-extent', function () { @@ -39,7 +39,9 @@ describe('normalize-extent', function () { normalizeExtent([-180, -90, 180, 'foo'], { wkid: 4326 }); should.fail(); } catch (error) { - error.message.should.equal('Received invalid extent: [-180,-90,180,"foo"]'); + error.message.should.equal( + 'Received invalid extent: [-180,-90,180,"foo"]', + ); } }); @@ -50,7 +52,7 @@ describe('normalize-extent', function () { ymin: -90, xmax: 180, ymax: 90, - spatialReference: { wkid: 4326 } + spatialReference: { wkid: 4326 }, }); }); @@ -61,7 +63,7 @@ describe('normalize-extent', function () { ymin: -90, xmax: 180, ymax: 90, - spatialReference: { wkid: 4326 } + spatialReference: { wkid: 4326 }, }); }); @@ -85,7 +87,13 @@ describe('normalize-extent', function () { it('corner array with NaNs should throw error', () => { try { - normalizeExtent([[3, 'food'], [4, 5]], { wkid: 4326 }); + normalizeExtent( + [ + [3, 'food'], + [4, 5], + ], + { wkid: 4326 }, + ); should.fail(); } catch (error) { error.message.should.equal('Received invalid extent: [[3,"food"],[4,5]]'); @@ -94,7 +102,13 @@ describe('normalize-extent', function () { it('corner array with too many coordinates should throw error', () => { try { - normalizeExtent([[3, 5, 7], [4, 5]], { wkid: 4326 }); + normalizeExtent( + [ + [3, 5, 7], + [4, 5], + ], + { wkid: 4326 }, + ); should.fail(); } catch (error) { error.message.should.equal('Received invalid extent: [[3,5,7],[4,5]]'); @@ -102,52 +116,64 @@ describe('normalize-extent', function () { }); it('corner extent array should return Esri Extent', () => { - const result = normalizeExtent([[-180, -90], [180, 90]], { wkid: 4326 }); + const result = normalizeExtent( + [ + [-180, -90], + [180, 90], + ], + { wkid: 4326 }, + ); result.should.deepEqual({ xmin: -180, ymin: -90, xmax: 180, ymax: 90, - spatialReference: { wkid: 4326 } + spatialReference: { wkid: 4326 }, }); }); it('Complete Esri extent passed in should get returned', () => { - const result = normalizeExtent({ - xmin: 40, - ymin: 10, - xmax: 55, - ymax: 25, - spatialReference: { - wkid: 4326 - } - }, { - wkid: 3857 - }); + const result = normalizeExtent( + { + xmin: 40, + ymin: 10, + xmax: 55, + ymax: 25, + spatialReference: { + wkid: 4326, + }, + }, + { + wkid: 3857, + }, + ); result.should.deepEqual({ xmin: 40, ymin: 10, xmax: 55, ymax: 25, - spatialReference: { wkid: 4326 } + spatialReference: { wkid: 4326 }, }); }); it('Esri extent without spatial ref, should get spatial ref added', () => { - const result = normalizeExtent({ - xmin: 40, - ymin: 10, - xmax: 55, - ymax: 25 - }, { - wkid: 4326 - }); + const result = normalizeExtent( + { + xmin: 40, + ymin: 10, + xmax: 55, + ymax: 25, + }, + { + wkid: 4326, + }, + ); result.should.deepEqual({ xmin: 40, ymin: 10, xmax: 55, ymax: 25, - spatialReference: { wkid: 4326 } + spatialReference: { wkid: 4326 }, }); }); }); diff --git a/packages/featureserver/src/helpers/normalize-input-data.js b/packages/featureserver/src/helpers/normalize-input-data.js index b0c82f897..c47ec692e 100644 --- a/packages/featureserver/src/helpers/normalize-input-data.js +++ b/packages/featureserver/src/helpers/normalize-input-data.js @@ -1,18 +1,17 @@ const getGeometryTypeFromGeojson = require('./get-geometry-type-from-geojson'); -module.exports = function normalizeInput (input = {}) { - const { - type, - tables, - layers, - relationships, - } = input; +module.exports = function normalizeInput(input = {}) { + const { type, tables, layers, relationships } = input; const geometryType = getGeometryTypeFromGeojson(input); return { - layers: layers || type === 'FeatureCollection' && geometryType && [input] || [], - tables: tables || type === 'FeatureCollection' && !geometryType && [input] || [], - relationships: relationships || [] + layers: + layers || (type === 'FeatureCollection' && geometryType && [input]) || [], + tables: + tables || + (type === 'FeatureCollection' && !geometryType && [input]) || + [], + relationships: relationships || [], }; }; diff --git a/packages/featureserver/src/helpers/normalize-request-params.js b/packages/featureserver/src/helpers/normalize-request-params.js index 1759ba706..559a66bcf 100644 --- a/packages/featureserver/src/helpers/normalize-request-params.js +++ b/packages/featureserver/src/helpers/normalize-request-params.js @@ -1,7 +1,7 @@ const _ = require('lodash'); const defaults = require('../metadata-defaults'); -function normalizeRequestParameters ( +function normalizeRequestParameters( query, body, maxRecordCount = defaults.maxRecordCount(), @@ -16,8 +16,10 @@ function normalizeRequestParameters ( .mapValues(coerceStrings) .value(); - const { resultRecordCount, ...params } = { ...definedQueryParams, ...definedBodyParams }; - + const { resultRecordCount, ...params } = { + ...definedQueryParams, + ...definedBodyParams, + }; return { ...params, @@ -44,9 +46,10 @@ function coerceStrings(val) { function tryParse(value) { try { return JSON.parse(value); + // eslint-disable-next-line } catch (e) { return value; } } -module.exports = { normalizeRequestParameters }; \ No newline at end of file +module.exports = { normalizeRequestParameters }; diff --git a/packages/featureserver/src/helpers/normalize-request-params.spec.js b/packages/featureserver/src/helpers/normalize-request-params.spec.js index b6f03b1b3..6de7e6789 100644 --- a/packages/featureserver/src/helpers/normalize-request-params.spec.js +++ b/packages/featureserver/src/helpers/normalize-request-params.spec.js @@ -9,7 +9,10 @@ describe('normailizeRequestParameters', () => { }); it('should remove empty strings from query params', () => { - const result = normalizeRequestParameters({ test: '', foo: 'barb', boo: 400 }, {}); + const result = normalizeRequestParameters( + { test: '', foo: 'barb', boo: 400 }, + {}, + ); result.should.deepEqual({ foo: 'barb', boo: 400, resultRecordCount: 2000 }); }); @@ -31,20 +34,29 @@ describe('normailizeRequestParameters', () => { {}, ); result.should.deepEqual({ - test: { foo: 'bard'}, + test: { foo: 'bard' }, resultRecordCount: 2000, }); }); it('should merge body and query', () => { - const result = normalizeRequestParameters({ resultRecordCount: '99' }, { foo: 'bart' }); + const result = normalizeRequestParameters( + { resultRecordCount: '99' }, + { foo: 'bart' }, + ); result.should.deepEqual({ resultRecordCount: 99, foo: 'bart' }); }); it('should coerce body string parameters', () => { const result = normalizeRequestParameters( {}, - { boolTrue: 'true', boolFalse: 'false', numberInt: '1', numberDecimal: '1.1', emptyParam: '' }, + { + boolTrue: 'true', + boolFalse: 'false', + numberInt: '1', + numberDecimal: '1.1', + emptyParam: '', + }, ); result.should.deepEqual({ boolTrue: true, diff --git a/packages/featureserver/src/helpers/normalize-spatial-reference.js b/packages/featureserver/src/helpers/normalize-spatial-reference.js index b2fc62cd1..afaa6eeb1 100644 --- a/packages/featureserver/src/helpers/normalize-spatial-reference.js +++ b/packages/featureserver/src/helpers/normalize-spatial-reference.js @@ -9,17 +9,22 @@ const schema = Joi.alternatives( Joi.object({ wkid: Joi.number().integer().optional(), latestWkid: Joi.number().integer().optional(), - wkt: Joi.string().optional() - }).unknown().or('wkid', 'latestWkid', 'wkt').required() + wkt: Joi.string().optional(), + }) + .unknown() + .or('wkid', 'latestWkid', 'wkt') + .required(), ); -function normalizeSpatialReference (input) { +function normalizeSpatialReference(input) { if (!input) return { wkid: 4326, latestWkid: 4326 }; const { error } = schema.validate(input); if (error) { - logManager.logger.verbose(` ${input} is not a valid spatial reference; defaulting to none, error: ${error}`); + logManager.logger.verbose( + ` ${input} is not a valid spatial reference; defaulting to none, error: ${error}`, + ); // Todo: throw error return { wkid: 4326, latestWkid: 4326 }; @@ -28,60 +33,70 @@ function normalizeSpatialReference (input) { const { type, value } = parseSpatialReferenceInput(input); if (type === 'wkid') { - return wktLookup.get(value) || esriWktLookup(value) || { wkid: 4326, latestWkid: 4326 }; + return ( + wktLookup.get(value) || + esriWktLookup(value) || { wkid: 4326, latestWkid: 4326 } + ); } - return convertStringToSpatialReference(value) || { wkid: 4326, latestWkid: 4326 }; + return ( + convertStringToSpatialReference(value) || { wkid: 4326, latestWkid: 4326 } + ); } -function parseSpatialReferenceInput (spatialReference) { +function parseSpatialReferenceInput(spatialReference) { // Search input for a wkid if (isNumericSpatialReferenceId(spatialReference)) { return { type: 'wkid', - value: Number(spatialReference) + value: Number(spatialReference), }; } if (isPrefixedSpatialReferenceId(spatialReference)) { return { type: 'wkid', - value: extractPrefixedSpatialReferenceId(spatialReference) + value: extractPrefixedSpatialReferenceId(spatialReference), }; } if (spatialReference.wkid || spatialReference.latestWkid) { return { type: 'wkid', - value: spatialReference.wkid || spatialReference.latestWkid + value: spatialReference.wkid || spatialReference.latestWkid, }; } return { type: 'wkt', - value: spatialReference.wkt || spatialReference + value: spatialReference.wkt || spatialReference, }; } -function isNumericSpatialReferenceId (spatialReference) { - return Number.isInteger(spatialReference) || Number.isInteger(Number(spatialReference)); +function isNumericSpatialReferenceId(spatialReference) { + return ( + Number.isInteger(spatialReference) || + Number.isInteger(Number(spatialReference)) + ); } -function isPrefixedSpatialReferenceId (spatialReference) { +function isPrefixedSpatialReferenceId(spatialReference) { return /[A-Z]+:/.test(spatialReference); } -function extractPrefixedSpatialReferenceId (prefixedId) { +function extractPrefixedSpatialReferenceId(prefixedId) { const spatialRefId = prefixedId.match(/[A-Z]*:(.*)/)[1]; return Number(spatialRefId); } -function esriWktLookup (lookupValue) { +function esriWktLookup(lookupValue) { const result = esriProjCodes.lookup(lookupValue); if (!result) { // Todo - throw error - logManager.logger.verbose(`An unknown spatial reference was detected: ${lookupValue}; defaulting to none`); + logManager.logger.verbose( + `An unknown spatial reference was detected: ${lookupValue}; defaulting to none`, + ); return; } @@ -93,19 +108,22 @@ function esriWktLookup (lookupValue) { return { latestWkid, wkid }; } -function convertStringToSpatialReference (wkt) { - if (/WGS_1984_Web_Mercator_Auxiliary_Sphere/.test(wkt)) return { wkid: 102100, latestWkid: 3857 }; +function convertStringToSpatialReference(wkt) { + if (/WGS_1984_Web_Mercator_Auxiliary_Sphere/.test(wkt)) + return { wkid: 102100, latestWkid: 3857 }; try { const wkid = getWktWkid(wkt); return wktLookup.get(wkid) || esriWktLookup(wkid) || { wkt }; } catch (err) { - logManager.logger.debug(`An un-parseable WKT spatial reference was detected: ${wkt}`); + logManager.logger.debug( + `An un-parseable WKT spatial reference was detected: ${wkt}; ${err.message}`, + ); // Todo: throw error } } -function getWktWkid (wkt) { +function getWktWkid(wkt) { const { AUTHORITY: authority } = wktParser(wkt); if (!authority) return; const [, wkid] = Object.entries(authority)[0]; diff --git a/packages/featureserver/src/helpers/normalize-spatial-reference.spec.js b/packages/featureserver/src/helpers/normalize-spatial-reference.spec.js index 4311eb22c..d63804b16 100644 --- a/packages/featureserver/src/helpers/normalize-spatial-reference.spec.js +++ b/packages/featureserver/src/helpers/normalize-spatial-reference.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const { normalizeSpatialReference } = require('.'); describe('normalize-spatial-reference', function () { @@ -6,7 +6,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference(); spatialRef.should.deepEqual({ latestWkid: 4326, - wkid: 4326 + wkid: 4326, }); }); @@ -14,7 +14,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference({ test: 'foo' }); spatialRef.should.deepEqual({ latestWkid: 4326, - wkid: 4326 + wkid: 4326, }); }); @@ -22,7 +22,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference(99999); spatialRef.should.deepEqual({ latestWkid: 4326, - wkid: 4326 + wkid: 4326, }); }); @@ -30,16 +30,17 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference('foodbar'); spatialRef.should.deepEqual({ latestWkid: 4326, - wkid: 4326 + wkid: 4326, }); }); it('object with wkt that is Web Mercator string', () => { - const inputWkt = 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; + const inputWkt = + 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; const spatialRef = normalizeSpatialReference({ wkt: inputWkt }); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 102100 + wkid: 102100, }); }); @@ -62,16 +63,17 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference({ wkt: inputWkt }); spatialRef.should.deepEqual({ latestWkid: 2229, - wkid: 102645 + wkid: 102645, }); }); it('Web Mercator wkt string', () => { - const inputWkt = 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; + const inputWkt = + 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; const spatialRef = normalizeSpatialReference(inputWkt); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 102100 + wkid: 102100, }); }); @@ -79,7 +81,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference('EPSG:3857'); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 3857 + wkid: 3857, }); }); @@ -87,7 +89,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference(3857); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 3857 + wkid: 3857, }); }); @@ -95,7 +97,7 @@ describe('normalize-spatial-reference', function () { const spatialRef = normalizeSpatialReference(102100); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 102100 + wkid: 102100, }); }); it('wkid 102100 extra properties', () => { @@ -111,11 +113,11 @@ describe('normalize-spatial-reference', function () { falseZ: -100000, zUnits: 10000, falseM: -100000, - mUnits: 10000 + mUnits: 10000, }); spatialRef.should.deepEqual({ latestWkid: 3857, - wkid: 102100 + wkid: 102100, }); }); it('wkid 7853 extra properties', () => { @@ -131,11 +133,11 @@ describe('normalize-spatial-reference', function () { falseZ: -100000, zUnits: 10000, falseM: -100000, - mUnits: 10000 + mUnits: 10000, }); spatialRef.should.deepEqual({ latestWkid: 7853, - wkid: 7853 + wkid: 7853, }); }); }); diff --git a/packages/featureserver/src/helpers/renderers.js b/packages/featureserver/src/helpers/renderers.js index ab05971ce..010693f7b 100644 --- a/packages/featureserver/src/helpers/renderers.js +++ b/packages/featureserver/src/helpers/renderers.js @@ -1,77 +1,52 @@ class PointRenderer { - constructor () { + constructor() { Object.assign(this, { type: 'simple', symbol: { - color: [ - 247, - 150, - 70, - 161 - ], + color: [247, 150, 70, 161], outline: { - color: [ - 190, - 190, - 190, - 105 - ], + color: [190, 190, 190, 105], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, size: 7.5, type: 'esriSMS', - style: 'esriSMSCircle' - } + style: 'esriSMSCircle', + }, }); } } class LineRenderer { - constructor () { + constructor() { Object.assign(this, { type: 'simple', symbol: { - color: [ - 247, - 150, - 70, - 204 - ], + color: [247, 150, 70, 204], width: 6.999999999999999, type: 'esriSLS', - style: 'esriSLSSolid' - } + style: 'esriSLSSolid', + }, }); } } class PolygonRenderer { - constructor () { + constructor() { Object.assign(this, { type: 'simple', symbol: { - color: [ - 75, - 172, - 198, - 161 - ], + color: [75, 172, 198, 161], outline: { - color: [ - 150, - 150, - 150, - 155 - ], + color: [150, 150, 150, 155], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, type: 'esriSFS', - style: 'esriSFSSolid' - } + style: 'esriSFSSolid', + }, }); } } @@ -79,5 +54,5 @@ class PolygonRenderer { module.exports = { PointRenderer, PolygonRenderer, - LineRenderer + LineRenderer, }; diff --git a/packages/featureserver/src/helpers/renderers.spec.js b/packages/featureserver/src/helpers/renderers.spec.js index 6f1d9c249..cef3429b4 100644 --- a/packages/featureserver/src/helpers/renderers.spec.js +++ b/packages/featureserver/src/helpers/renderers.spec.js @@ -1,11 +1,7 @@ const should = require('should'); should.config.checkProtoEql = false; -const { - PointRenderer, - PolygonRenderer, - LineRenderer -} = require('./renderers'); +const { PointRenderer, PolygonRenderer, LineRenderer } = require('./renderers'); describe('Renderers', () => { it('should produce default PointRenderer instance', () => { @@ -13,27 +9,17 @@ describe('Renderers', () => { renderer.should.deepEqual({ type: 'simple', symbol: { - color: [ - 247, - 150, - 70, - 161 - ], + color: [247, 150, 70, 161], outline: { - color: [ - 190, - 190, - 190, - 105 - ], + color: [190, 190, 190, 105], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, size: 7.5, type: 'esriSMS', - style: 'esriSMSCircle' - } + style: 'esriSMSCircle', + }, }); }); @@ -42,16 +28,11 @@ describe('Renderers', () => { renderer.should.deepEqual({ type: 'simple', symbol: { - color: [ - 247, - 150, - 70, - 204 - ], + color: [247, 150, 70, 204], width: 6.999999999999999, type: 'esriSLS', - style: 'esriSLSSolid' - } + style: 'esriSLSSolid', + }, }); }); @@ -60,26 +41,16 @@ describe('Renderers', () => { renderer.should.deepEqual({ type: 'simple', symbol: { - color: [ - 75, - 172, - 198, - 161 - ], + color: [75, 172, 198, 161], outline: { - color: [ - 150, - 150, - 150, - 155 - ], + color: [150, 150, 150, 155], width: 0.5, type: 'esriSLS', - style: 'esriSLSSolid' + style: 'esriSLSSolid', }, type: 'esriSFS', - style: 'esriSFSSolid' - } + style: 'esriSFSSolid', + }, }); }); }); diff --git a/packages/featureserver/src/helpers/table-layer-metadata.js b/packages/featureserver/src/helpers/table-layer-metadata.js index 36873cf4f..8f0c53dbf 100644 --- a/packages/featureserver/src/helpers/table-layer-metadata.js +++ b/packages/featureserver/src/helpers/table-layer-metadata.js @@ -2,56 +2,54 @@ const _ = require('lodash'); const joi = require('joi'); const defaults = require('../metadata-defaults'); const logManager = require('../log-manager'); -const { - LayerFields -} = require('./fields'); +const { LayerFields } = require('./fields'); -const supportedQueryFormatsArraySchema = joi.array().items( - joi.string().allow('JSON', 'geojson', 'PBF') -).has(joi.string().valid('JSON')).message('must contain "JSON"'); +const supportedQueryFormatsArraySchema = joi + .array() + .items(joi.string().allow('JSON', 'geojson', 'PBF')) + .has(joi.string().valid('JSON')) + .message('must contain "JSON"'); -const supportedQueryFormatsSchema = joi.alternatives().try(supportedQueryFormatsArraySchema, joi.string()); +const supportedQueryFormatsSchema = joi + .alternatives() + .try(supportedQueryFormatsArraySchema, joi.string()); class TableLayerMetadata { - static create (geojson, options = {}) { - const { - geojson: normalizedGeojson, - options: normalizedOptions - } = TableLayerMetadata.normalizeInput(geojson, options); + static create(geojson, options = {}) { + const { geojson: normalizedGeojson, options: normalizedOptions } = + TableLayerMetadata.normalizeInput(geojson, options); const tableMetadata = new TableLayerMetadata(); return tableMetadata.mixinOverrides(normalizedGeojson, normalizedOptions); } - static normalizeInput (geojson, req) { - const { - metadata = {}, - capabilities, - ...normalizedGeojson - } = geojson; + static normalizeInput(geojson, req) { + const { metadata = {}, capabilities, ...normalizedGeojson } = geojson; - const { - params: { - layer: reqLayer - } = {}, - query = {} - } = req; + const { params: { layer: reqLayer } = {}, query = {} } = req; const layerId = reqLayer != null ? reqLayer : req.layerId; // TODO: deprecate req.app.locals.config usage - const { - currentVersion, - description - } = _.get(req, 'app.locals.config.featureServer', {}); - - const normalizedOptions = _.pickBy({ - currentVersion, - description, - layerId, - ...query, - ...metadata, - capabilities: normalizeCapabilities(capabilities, metadata.capabilities) - }, (value) => value); + const { currentVersion, description } = _.get( + req, + 'app.locals.config.featureServer', + {}, + ); + + const normalizedOptions = _.pickBy( + { + currentVersion, + description, + layerId, + ...query, + ...metadata, + capabilities: normalizeCapabilities( + capabilities, + metadata.capabilities, + ), + }, + (value) => value, + ); if (!normalizedGeojson.features) { normalizedGeojson.features = []; @@ -59,15 +57,15 @@ class TableLayerMetadata { return { geojson: normalizedGeojson, - options: normalizedOptions + options: normalizedOptions, }; } - constructor () { + constructor() { Object.assign(this, defaults.tableLayerDefaults()); } - mixinOverrides (geojson = {}, options = {}) { + mixinOverrides(geojson = {}, options = {}) { const { id, idField = 'OBJECTID', @@ -103,14 +101,14 @@ class TableLayerMetadata { return this; } - _setFields (data, options) { + _setFields(data, options) { const fields = LayerFields.create({ ...data, ...options }); if (fields) { this.fields = fields; } } - _setId (layerId, metadataId) { + _setId(layerId, metadataId) { const requestPathLayerId = parseInt(layerId); const id = !isNaN(requestPathLayerId) ? requestPathLayerId : metadataId; @@ -119,7 +117,7 @@ class TableLayerMetadata { } } - _setDisplayField (displayField, idField) { + _setDisplayField(displayField, idField) { const overrideDisplayField = displayField || idField; if (overrideDisplayField) { @@ -127,13 +125,13 @@ class TableLayerMetadata { } } - _setHasStaticData (hasStaticData) { + _setHasStaticData(hasStaticData) { if (typeof hasStaticData === 'boolean') { this.hasStaticData = hasStaticData; } } - _setCapabilities (capabilities) { + _setCapabilities(capabilities) { if (!capabilities) { return; } @@ -143,30 +141,33 @@ class TableLayerMetadata { return; } - if (_.has(capabilities, 'extract') && !this.capabilities.includes('Extract')) { + if ( + _.has(capabilities, 'extract') && + !this.capabilities.includes('Extract') + ) { this.capabilities = `${this.capabilities},Extract`; } } - _setUniqueIdField (idField) { + _setUniqueIdField(idField) { if (idField) { this.uniqueIdField.name = idField; } } - _setPagination (supportsPagination) { + _setPagination(supportsPagination) { if (typeof supportsPagination === 'boolean') { this.advancedQueryCapabilities.supportsPagination = supportsPagination; } } - _setHasAttachments (hasAttachments) { + _setHasAttachments(hasAttachments) { if (hasAttachments != null && typeof hasAttachments === 'boolean') { this.hasAttachments = hasAttachments; } } - _setDirectOverrides (options) { + _setDirectOverrides(options) { const { name, relationships, @@ -178,7 +179,7 @@ class TableLayerMetadata { maxRecordCount, defaultVisibility, currentVersion, - hasZ + hasZ, } = options; _.merge(this, { @@ -192,24 +193,26 @@ class TableLayerMetadata { maxRecordCount, defaultVisibility, currentVersion, - hasZ + hasZ, }); } - #setSupportedQueryFormats (supportedQueryFormats) { - if(!supportedQueryFormats) { + #setSupportedQueryFormats(supportedQueryFormats) { + if (!supportedQueryFormats) { return; } try { validateQueryFormatsArray(supportedQueryFormats); - + if (Array.isArray(supportedQueryFormats)) { this.supportedQueryFormats = supportedQueryFormats.join(','); return; } - - validateQueryFormatsArray(supportedQueryFormats.split(',').map(val => val.trim())); + + validateQueryFormatsArray( + supportedQueryFormats.split(',').map((val) => val.trim()), + ); this.supportedQueryFormats = supportedQueryFormats; } catch (error) { logManager.logger.error(error.message); @@ -217,24 +220,26 @@ class TableLayerMetadata { } } -function normalizeCapabilities (capabilities, metadataCapabilites) { +function normalizeCapabilities(capabilities, metadataCapabilites) { if (_.isString(metadataCapabilites)) { return { ...capabilities, - list: metadataCapabilites + list: metadataCapabilites, }; } return { ...(metadataCapabilites || {}), - ...capabilities + ...capabilities, }; } function validateQueryFormatsArray(arr) { const { error } = supportedQueryFormatsSchema.validate(arr); if (error) { - throw new Error (`"supportedQueryFormats" override is invalid; ${error.message}. skipping override`); + throw new Error( + `"supportedQueryFormats" override is invalid; ${error.message}. skipping override`, + ); } } diff --git a/packages/featureserver/src/helpers/table-layer-metadata.spec.js b/packages/featureserver/src/helpers/table-layer-metadata.spec.js index 7ec0e049e..a3dc1972c 100644 --- a/packages/featureserver/src/helpers/table-layer-metadata.spec.js +++ b/packages/featureserver/src/helpers/table-layer-metadata.spec.js @@ -14,12 +14,12 @@ const fields = { }; const loggerSpy = { - error: sinon.spy() + error: sinon.spy(), }; const TableLayerMetadata = proxyquire('./table-layer-metadata', { '../helpers/fields': fields, - '../log-manager': { logger: loggerSpy } + '../log-manager': { logger: loggerSpy }, }); describe('TableLayerMetadata', () => { @@ -2075,7 +2075,7 @@ describe('TableLayerMetadata', () => { tableLayerMetadata.mixinOverrides( {}, { - supportedQueryFormats: 'JSON' + supportedQueryFormats: 'JSON', }, ); tableLayerMetadata.supportedQueryFormats.should.equal('JSON'); @@ -2086,7 +2086,7 @@ describe('TableLayerMetadata', () => { tableLayerMetadata.mixinOverrides( {}, { - supportedQueryFormats: 'JSON, geojson' + supportedQueryFormats: 'JSON, geojson', }, ); tableLayerMetadata.supportedQueryFormats.should.equal('JSON, geojson'); @@ -2097,23 +2097,25 @@ describe('TableLayerMetadata', () => { tableLayerMetadata.mixinOverrides( {}, { - supportedQueryFormats: ['JSON'] + supportedQueryFormats: ['JSON'], }, ); tableLayerMetadata.supportedQueryFormats.should.equal('JSON'); }); - + it('skip override if string missing JSON', () => { const tableLayerMetadata = new TableLayerMetadata(); tableLayerMetadata.mixinOverrides( {}, { - supportedQueryFormats: ['PBF'] + supportedQueryFormats: ['PBF'], }, ); - tableLayerMetadata.supportedQueryFormats.should.equal('JSON,geojson,PBF'); + tableLayerMetadata.supportedQueryFormats.should.equal( + 'JSON,geojson,PBF', + ); loggerSpy.error.firstCall.args.should.deepEqual([ - '"supportedQueryFormats" override is invalid; must contain "JSON". skipping override' + '"supportedQueryFormats" override is invalid; must contain "JSON". skipping override', ]); }); }); @@ -2325,19 +2327,17 @@ describe('TableLayerMetadata', () => { }); it('static method "create" should handle missing options', () => { - const tableLayerMetadata = TableLayerMetadata.create( - { - features: ['feature'], - metadata: { - foo: 'bar', - displayField: 'myField', - capabilities: 'list,of,stuff', - }, - capabilities: { - world: 'hellow', - }, - } - ); + const tableLayerMetadata = TableLayerMetadata.create({ + features: ['feature'], + metadata: { + foo: 'bar', + displayField: 'myField', + capabilities: 'list,of,stuff', + }, + capabilities: { + world: 'hellow', + }, + }); tableLayerMetadata.should.deepEqual({ currentVersion: 11.2, @@ -2346,7 +2346,8 @@ describe('TableLayerMetadata', () => { name: 'Not Set', type: 'Table', displayField: 'myField', - description: 'This is a feature layer exposed with Koop. For more information go to https://github.com/koopjs/koop.', + description: + 'This is a feature layer exposed with Koop. For more information go to https://github.com/koopjs/koop.', copyrightText: 'Copyright information varies by provider. For more information please contact the source of this data.', defaultVisibility: true, diff --git a/packages/featureserver/src/helpers/validate-inputs.spec.js b/packages/featureserver/src/helpers/validate-inputs.spec.js index 9cb81b218..722ad5fd9 100644 --- a/packages/featureserver/src/helpers/validate-inputs.spec.js +++ b/packages/featureserver/src/helpers/validate-inputs.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const sinon = require('sinon'); require('should-sinon'); const proxyquire = require('proxyquire'); @@ -17,13 +17,13 @@ describe('validateInputs', () => { const { validateInputs } = proxyquire('./validate-inputs', { 'geojson-validation': { - valid: hintSpy + valid: hintSpy, }, '../log-manager': { logger: { - debug: debugSpy - } - } + debug: debugSpy, + }, + }, }); validateInputs({}, { foo: 'geojson' }); @@ -36,13 +36,13 @@ describe('validateInputs', () => { it('should skip geojson validation', () => { const { validateInputs } = proxyquire('./validate-inputs', { 'geojson-validation': { - valid: hintSpy + valid: hintSpy, }, '../log-manager': { logger: { - debug: debugSpy - } - } + debug: debugSpy, + }, + }, }); validateInputs({}, { foo: 'geojson' }); hintSpy.notCalled.should.equal(true); @@ -61,7 +61,7 @@ describe('validateInputs', () => { try { validateInputs({}, { metadata: { maxRecordCount: 1 } }); } catch (error) { - throw new Error('should not have thrown'); + throw new Error(`should not have thrown; ${error}`); } }); @@ -80,7 +80,7 @@ describe('validateInputs', () => { try { validateInputs({ foo: 'bar', resultRecordCount: 1 }, {}); } catch (error) { - throw new Error('should not have thrown'); + throw new Error(`should not have thrown; ${error}`); } }); @@ -93,4 +93,4 @@ describe('validateInputs', () => { } }); }); -}); \ No newline at end of file +}); diff --git a/packages/featureserver/src/index.js b/packages/featureserver/src/index.js index 34ed8d7b9..2445f2c07 100644 --- a/packages/featureserver/src/index.js +++ b/packages/featureserver/src/index.js @@ -11,5 +11,5 @@ module.exports = { queryRelatedRecords: require('./queryRelatedRecords.js'), generateRenderer: require('./generate-renderer'), setLogger, - setDefaults: defaults.setDefaults.bind(defaults) + setDefaults: defaults.setDefaults.bind(defaults), }; diff --git a/packages/featureserver/src/layer-metadata.js b/packages/featureserver/src/layer-metadata.js index 663fbb13d..47d5f7cbf 100644 --- a/packages/featureserver/src/layer-metadata.js +++ b/packages/featureserver/src/layer-metadata.js @@ -1,10 +1,10 @@ const { isTable, TableLayerMetadata, - FeatureLayerMetadata + FeatureLayerMetadata, } = require('./helpers'); -function layerMetadata (data = {}, options = {}) { +function layerMetadata(data = {}, options = {}) { if (isTable({ ...data, ...options })) { return TableLayerMetadata.create(data, options); } diff --git a/packages/featureserver/src/layer-metadata.spec.js b/packages/featureserver/src/layer-metadata.spec.js index 04024ba76..a7f03e389 100644 --- a/packages/featureserver/src/layer-metadata.spec.js +++ b/packages/featureserver/src/layer-metadata.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); const sinon = require('sinon'); const proxyquire = require('proxyquire'); const TableCreateSpy = sinon.spy(function () { @@ -10,38 +10,48 @@ const FeatureLayerCreateSpy = sinon.spy(function () { describe('layerMetadata', function () { it('isTable === true, returns TableLayerMetadata instance', () => { - const isTableSpy = sinon.spy(function () { return true; }); + const isTableSpy = sinon.spy(function () { + return true; + }); const layerMetadata = proxyquire('./layer-metadata', { './helpers': { isTable: isTableSpy, TableLayerMetadata: { create: TableCreateSpy }, - FeatureLayerMetadata: { create: FeatureLayerCreateSpy } - } + FeatureLayerMetadata: { create: FeatureLayerCreateSpy }, + }, }); const result = layerMetadata({ foo: 'bar' }, { sna: 'fu' }); should(result).deepEqual('table-layer-metadata'); isTableSpy.callCount.should.equal(1); isTableSpy.firstCall.args.should.deepEqual([{ foo: 'bar', sna: 'fu' }]); TableCreateSpy.callCount.should.equal(1); - TableCreateSpy.firstCall.args.should.deepEqual([{ foo: 'bar' }, { sna: 'fu' }]); + TableCreateSpy.firstCall.args.should.deepEqual([ + { foo: 'bar' }, + { sna: 'fu' }, + ]); TableCreateSpy.resetHistory(); }); it('isTable === false, returns FeatureLayerMetadata instance', () => { - const isTableSpy = sinon.spy(function () { return false; }); + const isTableSpy = sinon.spy(function () { + return false; + }); const layerMetadata = proxyquire('./layer-metadata', { './helpers': { isTable: isTableSpy, TableLayerMetadata: { create: TableCreateSpy }, - FeatureLayerMetadata: { create: FeatureLayerCreateSpy } - } + FeatureLayerMetadata: { create: FeatureLayerCreateSpy }, + }, }); const result = layerMetadata({ foo: 'bar' }, { sna: 'fu' }); should(result).deepEqual('feature-layer-metadata'); isTableSpy.callCount.should.equal(1); isTableSpy.firstCall.args.should.deepEqual([{ foo: 'bar', sna: 'fu' }]); FeatureLayerCreateSpy.callCount.should.equal(1); - FeatureLayerCreateSpy.firstCall.args.should.deepEqual([{ foo: 'bar' }, { sna: 'fu' }]); + FeatureLayerCreateSpy.firstCall.args.should.deepEqual([ + { foo: 'bar' }, + { sna: 'fu' }, + ]); FeatureLayerCreateSpy.resetHistory(); }); }); diff --git a/packages/featureserver/src/layers-metadata.js b/packages/featureserver/src/layers-metadata.js index 0aca3ab36..6211fbd82 100644 --- a/packages/featureserver/src/layers-metadata.js +++ b/packages/featureserver/src/layers-metadata.js @@ -1,10 +1,10 @@ const { normalizeInputData, TableLayerMetadata, - FeatureLayerMetadata + FeatureLayerMetadata, } = require('./helpers'); -module.exports = function layersMetadata (data, options = {}) { +module.exports = function layersMetadata(data, options = {}) { const { layers: layersInput, tables: tablesInput } = normalizeInputData(data); const layers = layersInput.map((layer, i) => { @@ -12,7 +12,10 @@ module.exports = function layersMetadata (data, options = {}) { }); const tables = tablesInput.map((table, i) => { - return TableLayerMetadata.create(table, { layerId: layers.length + i, ...options }); + return TableLayerMetadata.create(table, { + layerId: layers.length + i, + ...options, + }); }); return { layers, tables }; diff --git a/packages/featureserver/src/layers-metadata.spec.js b/packages/featureserver/src/layers-metadata.spec.js index 6c5265e37..4ec8dac72 100644 --- a/packages/featureserver/src/layers-metadata.spec.js +++ b/packages/featureserver/src/layers-metadata.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); should.config.checkProtoEql = false; const sinon = require('sinon'); const proxyquire = require('proxyquire'); @@ -8,7 +8,7 @@ describe('layers metadata', () => { const normalizeInputData = sinon.spy(function () { return { layers: [], - tables: [] + tables: [], }; }); const TableLayerMetadata = sinon.spy(); @@ -18,15 +18,15 @@ describe('layers metadata', () => { './helpers': { normalizeInputData, TableLayerMetadata, - FeatureLayerMetadata - } + FeatureLayerMetadata, + }, }); const layersInfo = layersInfoHandler({}); layersInfo.should.deepEqual({ layers: [], - tables: [] + tables: [], }); normalizeInputData.callCount.should.equal(1); @@ -39,13 +39,13 @@ describe('layers metadata', () => { const normalizeInputData = sinon.spy(function () { return { layers: ['layer1', 'layer2'], - tables: ['table1'] + tables: ['table1'], }; }); const tableCreateSpy = sinon.spy(); const TableLayerMetadata = class TableClass { - static create (input, options) { + static create(input, options) { tableCreateSpy(input, options); return `${input}-metadata`; } @@ -53,7 +53,7 @@ describe('layers metadata', () => { const featureLayerCreateSpy = sinon.spy(); const FeatureLayerMetadata = class FeatureClass { - static create (input, options) { + static create(input, options) { featureLayerCreateSpy(input, options); return `${input}-metadata`; } @@ -63,23 +63,35 @@ describe('layers metadata', () => { './helpers': { normalizeInputData, TableLayerMetadata, - FeatureLayerMetadata - } + FeatureLayerMetadata, + }, }); - const layersInfo = layersInfoHandler({ hello: 'world' }, { some: 'options' }); + const layersInfo = layersInfoHandler( + { hello: 'world' }, + { some: 'options' }, + ); layersInfo.should.deepEqual({ layers: ['layer1-metadata', 'layer2-metadata'], - tables: ['table1-metadata'] + tables: ['table1-metadata'], }); normalizeInputData.callCount.should.equal(1); normalizeInputData.firstCall.args.should.deepEqual([{ hello: 'world' }]); featureLayerCreateSpy.callCount.should.equal(2); - featureLayerCreateSpy.firstCall.args.should.deepEqual(['layer1', { layerId: 0, some: 'options' }]); - featureLayerCreateSpy.secondCall.args.should.deepEqual(['layer2', { layerId: 1, some: 'options' }]); + featureLayerCreateSpy.firstCall.args.should.deepEqual([ + 'layer1', + { layerId: 0, some: 'options' }, + ]); + featureLayerCreateSpy.secondCall.args.should.deepEqual([ + 'layer2', + { layerId: 1, some: 'options' }, + ]); tableCreateSpy.callCount.should.equal(1); - tableCreateSpy.firstCall.args.should.deepEqual(['table1', { layerId: 2, some: 'options' }]); + tableCreateSpy.firstCall.args.should.deepEqual([ + 'table1', + { layerId: 2, some: 'options' }, + ]); }); }); diff --git a/packages/featureserver/src/log-manager.js b/packages/featureserver/src/log-manager.js index b89ca5107..e0f1980ca 100644 --- a/packages/featureserver/src/log-manager.js +++ b/packages/featureserver/src/log-manager.js @@ -1,9 +1,9 @@ -const Logger = require('@koopjs/logger'); +const Logger = require('@koopjs/logger'); let logger = new Logger(); const winnow = require('@koopjs/winnow'); module.exports = { - get logger () { + get logger() { return logger; }, @@ -14,9 +14,9 @@ module.exports = { winnow.setLogger({ logger }); return; } - + if (logLevel) { logger = new Logger({ logLevel }); } - } + }, }; diff --git a/packages/featureserver/src/metadata-defaults.js b/packages/featureserver/src/metadata-defaults.js index 2611341a2..b59a05bfa 100644 --- a/packages/featureserver/src/metadata-defaults.js +++ b/packages/featureserver/src/metadata-defaults.js @@ -39,7 +39,7 @@ const defaultOverridables = { description: LAYER_DESCRIPTION, copyrightText: COPYRIGHT, extent: EXTENT, - supportedQueryFormats: SUPPORTED_QUERY_FORMATS + supportedQueryFormats: SUPPORTED_QUERY_FORMATS, }, }; @@ -73,7 +73,7 @@ const overridablesSchema = joi.object({ description: joi.string().allow(null, ''), copyrightText: joi.string().allow(null, ''), extent: esriExtentSchema, - supportedQueryFormats: joi.string().allow('JSON', 'JSON,geojson') + supportedQueryFormats: joi.string().allow('JSON', 'JSON,geojson'), }), }); diff --git a/packages/featureserver/src/metadata-defaults.spec.js b/packages/featureserver/src/metadata-defaults.spec.js index b1f732202..12c4b5a60 100644 --- a/packages/featureserver/src/metadata-defaults.spec.js +++ b/packages/featureserver/src/metadata-defaults.spec.js @@ -12,19 +12,20 @@ describe('server config options', () => { settings.currentVersion.should.equal(99.1); }); - it('should not be able to set invalid values', () => { try { const result = defaults.setDefaults({ server: { spatialReference: {} } }); result.should.be.undefined(); } catch (error) { - error.message.should.equal('FeatureServer default settings are invalid: "server.spatialReference.wkid" is required.'); - } + error.message.should.equal( + 'FeatureServer default settings are invalid: "server.spatialReference.wkid" is required.', + ); + } }); it('should ignore unknown keys', () => { defaults.setDefaults({ foo: 'bar' }); const settings = defaults.serverDefaults(); - settings.foo?.should.be.undefined(); + settings.foo?.should.be.undefined(); }); }); diff --git a/packages/featureserver/src/query/filter-and-transform.js b/packages/featureserver/src/query/filter-and-transform.js index 3c544f1b3..b86e8b279 100644 --- a/packages/featureserver/src/query/filter-and-transform.js +++ b/packages/featureserver/src/query/filter-and-transform.js @@ -1,7 +1,7 @@ const { query } = require('@koopjs/winnow'); const helpers = require('../helpers'); -function filterAndTransform (json, requestParams) { +function filterAndTransform(json, requestParams) { const { features, type, ...restJson } = json; const params = FilterAndTransformParams.create(requestParams) .removeParamsAlreadyApplied(json.filtersApplied) @@ -15,35 +15,34 @@ function filterAndTransform (json, requestParams) { if (outStatistics) { return { statistics: result, - ...restJson + ...restJson, }; } - return result; } class FilterAndTransformParams { - static create (requestParams) { + static create(requestParams) { return new FilterAndTransformParams(requestParams); } - static standardize (requestParams) { - const {returnDistinctValues, where = '1=1', ...rest } = requestParams; - + static standardize(requestParams) { + const { returnDistinctValues, where = '1=1', ...rest } = requestParams; + return { ...rest, distinct: !!returnDistinctValues, - where: extractPlusPlaceHolders(where) + where: extractPlusPlaceHolders(where), }; } - constructor (requestParams) { + constructor(requestParams) { const params = FilterAndTransformParams.standardize(requestParams); Object.assign(this, params); } - removeParamsAlreadyApplied (alreadyApplied) { + removeParamsAlreadyApplied(alreadyApplied) { for (const key in alreadyApplied) { if (key === 'projection') { delete this.outSR; @@ -59,14 +58,19 @@ class FilterAndTransformParams { return this; } - addToEsri () { + addToEsri() { this.toEsri = this.f !== 'geojson' && !this.returnExtentOnly; return this; } - addInputCrs (data) { + addInputCrs(data) { const { metadata = {} } = data; - this.inputCrs = this.inputCrs || this.sourceSR || metadata.crs || helpers.getCollectionCrs(data) || 4326; + this.inputCrs = + this.inputCrs || + this.sourceSR || + metadata.crs || + helpers.getCollectionCrs(data) || + 4326; delete this.sourceSR; return this; } @@ -80,7 +84,7 @@ function extractPlusPlaceHolders(where) { const charArray = Array.from(whereWithReplacedSingleQuotes); return charArray .map((char) => { - if (char === '\'' && !openDouble) { + if (char === "'" && !openDouble) { openSingle = !openSingle; } @@ -94,6 +98,6 @@ function extractPlusPlaceHolders(where) { return char; }) .join('') - .replace(/~~xxx~~/g, '\'\''); + .replace(/~~xxx~~/g, "''"); } module.exports = { filterAndTransform }; diff --git a/packages/featureserver/src/query/filter-and-transform.spec.js b/packages/featureserver/src/query/filter-and-transform.spec.js index e11d9a68a..4af15f279 100644 --- a/packages/featureserver/src/query/filter-and-transform.spec.js +++ b/packages/featureserver/src/query/filter-and-transform.spec.js @@ -44,10 +44,7 @@ describe('filterAndTransform', () => { }); it('should set a default 1=1 for an undefined where', () => { - const result = filterAndTransform( - { features: [{}] }, - { }, - ); + const result = filterAndTransform({ features: [{}] }, {}); result.should.deepEqual({ features: 'expected-result', }); @@ -69,14 +66,19 @@ describe('filterAndTransform', () => { filterAndTransformSpy.callCount.should.equal(1); filterAndTransformSpy.firstCall.args.should.deepEqual([ { features: [{}] }, - { inputCrs: 4326, toEsri: true, distinct: false, where: 'FOO IS NOT NULL' }, + { + inputCrs: 4326, + toEsri: true, + distinct: false, + where: 'FOO IS NOT NULL', + }, ]); }); it('should not remove "+" from where if wrapped in single quotes', () => { const result = filterAndTransform( { features: [{}] }, - { where: '\'FOO+\'+IS+NOT+NULL' }, + { where: "'FOO+'+IS+NOT+NULL" }, ); result.should.deepEqual({ features: 'expected-result', @@ -84,7 +86,12 @@ describe('filterAndTransform', () => { filterAndTransformSpy.callCount.should.equal(1); filterAndTransformSpy.firstCall.args.should.deepEqual([ { features: [{}] }, - { inputCrs: 4326, toEsri: true, distinct: false, where: '\'FOO+\' IS NOT NULL' }, + { + inputCrs: 4326, + toEsri: true, + distinct: false, + where: "'FOO+' IS NOT NULL", + }, ]); }); @@ -99,7 +106,12 @@ describe('filterAndTransform', () => { filterAndTransformSpy.callCount.should.equal(1); filterAndTransformSpy.firstCall.args.should.deepEqual([ { features: [{}] }, - { inputCrs: 4326, toEsri: true, distinct: false, where: '"FOO+" IS NOT NULL' }, + { + inputCrs: 4326, + toEsri: true, + distinct: false, + where: '"FOO+" IS NOT NULL', + }, ]); }); }); diff --git a/packages/featureserver/src/query/index.spec.js b/packages/featureserver/src/query/index.spec.js index e66c69146..4aee449cf 100644 --- a/packages/featureserver/src/query/index.spec.js +++ b/packages/featureserver/src/query/index.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const sinon = require('sinon'); const proxyquire = require('proxyquire'); @@ -29,26 +29,27 @@ const renderCountAndExtentResponseSpy = sinon.spy(function () { const stub = { './filter-and-transform': { - filterAndTransform: filterAndTransformSpy + filterAndTransform: filterAndTransformSpy, }, './log-provider-data-warnings': { - logProviderDataWarnings: logWarningsSpy + logProviderDataWarnings: logWarningsSpy, }, './render-features': { - renderFeaturesResponse: renderFeaturesResponseSpy + renderFeaturesResponse: renderFeaturesResponseSpy, }, './render-statistics': { - renderStatisticsResponse: renderStatisticsResponseSpy + renderStatisticsResponse: renderStatisticsResponseSpy, }, './render-precalculated-statistics': { - renderPrecalculatedStatisticsResponse: renderPrecalculatedStatisticsResponseSpy + renderPrecalculatedStatisticsResponse: + renderPrecalculatedStatisticsResponseSpy, }, './render-count-and-extent': { - renderCountAndExtentResponse: renderCountAndExtentResponseSpy + renderCountAndExtentResponse: renderCountAndExtentResponseSpy, }, '../helpers': { - getGeometryTypeFromGeojson: getGeometryTypeFromGeojsonSpy - } + getGeometryTypeFromGeojson: getGeometryTypeFromGeojsonSpy, + }, }; const queryHandler = proxyquire('./', stub); @@ -68,33 +69,36 @@ describe('query', () => { it('should render precalculated statistics', () => { const json = { statistics: 'statistics', - metadata: 'metadata' + metadata: 'metadata', }; const result = queryHandler(json, { outStatistics: ['stats'] }); result.should.equal('precalculated-statistics'); renderPrecalculatedStatisticsResponseSpy.callCount.should.equal(1); - renderPrecalculatedStatisticsResponseSpy.firstCall.args.should.deepEqual([json, { - outStatistics: ['stats'], - groupByFieldsForStatistics: undefined - }]); + renderPrecalculatedStatisticsResponseSpy.firstCall.args.should.deepEqual([ + json, + { + outStatistics: ['stats'], + groupByFieldsForStatistics: undefined, + }, + ]); }); it('should render extent and count', () => { const json = { extent: 'extent', - count: 'count' + count: 'count', }; const params = { returnExtentOnly: true, - returnCountOnly: true + returnCountOnly: true, }; const result = queryHandler(json, params); result.should.deepEqual({ extent: 'extent', - count: 'count' + count: 'count', }); renderPrecalculatedStatisticsResponseSpy.callCount.should.equal(0); }); @@ -102,16 +106,16 @@ describe('query', () => { it('should render extent', () => { const json = { extent: 'extent', - count: 'count' + count: 'count', }; const params = { - returnExtentOnly: true + returnExtentOnly: true, }; const result = queryHandler(json, params); result.should.deepEqual({ - extent: 'extent' + extent: 'extent', }); renderPrecalculatedStatisticsResponseSpy.callCount.should.equal(0); }); @@ -119,16 +123,16 @@ describe('query', () => { it('should render count', () => { const json = { extent: 'extent', - count: 'count' + count: 'count', }; const params = { - returnCountOnly: true + returnCountOnly: true, }; const result = queryHandler(json, params); result.should.deepEqual({ - count: 'count' + count: 'count', }); renderPrecalculatedStatisticsResponseSpy.callCount.should.equal(0); }); @@ -141,29 +145,23 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } + coordinates: [-104, 40], + }, }, { properties: { - OBJECTID: 1954528849 + OBJECTID: 1954528849, }, geometry: { type: 'Point', - coordinates: [ - -106, - 41 - ] - } - } - ] + coordinates: [-106, 41], + }, + }, + ], }; const params = { f: 'geojson' }; @@ -171,7 +169,7 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ type: 'FeatureCollection', - features: ['filtered-feature'] + features: ['filtered-feature'], }); filterAndTransformSpy.callCount.should.equal(1); filterAndTransformSpy.firstCall.args.should.deepEqual([json, params]); @@ -184,29 +182,23 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } + coordinates: [-104, 40], + }, }, { properties: { - OBJECTID: 1954528849 + OBJECTID: 1954528849, }, geometry: { type: 'Point', - coordinates: [ - -106, - 41 - ] - } - } - ] + coordinates: [-106, 41], + }, + }, + ], }; const params = { f: 'geojson' }; @@ -214,7 +206,7 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ type: 'FeatureCollection', - features: json.features + features: json.features, }); filterAndTransformSpy.callCount.should.equal(0); }); @@ -223,7 +215,7 @@ describe('query', () => { const json = { filtersApplied: { all: true }, type: 'FeatureCollection', - features: [] + features: [], }; const params = { f: 'geojson' }; @@ -231,7 +223,7 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ type: 'FeatureCollection', - features: json.features + features: json.features, }); filterAndTransformSpy.callCount.should.equal(0); }); @@ -244,17 +236,14 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { f: 'geojson' }; @@ -262,7 +251,7 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ type: 'FeatureCollection', - features: ['filtered-feature'] + features: ['filtered-feature'], }); logWarningsSpy.callCount.should.equal(1); }); @@ -275,17 +264,14 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnCountOnly: true }; @@ -302,17 +288,14 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnCountOnly: true }; @@ -320,13 +303,16 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual('count-or-extent'); renderCountAndExtentResponseSpy.callCount.should.equal(1); - renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([{ - features: ['filtered-feature'] - }, { - ...params, - outSR: undefined, - returnExtentOnly: undefined - }]); + renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([ + { + features: ['filtered-feature'], + }, + { + ...params, + outSR: undefined, + returnExtentOnly: undefined, + }, + ]); }); it('should return extent', () => { @@ -335,17 +321,14 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnExtentOnly: true }; @@ -353,13 +336,16 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual('count-or-extent'); renderCountAndExtentResponseSpy.callCount.should.equal(1); - renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([{ - features: ['filtered-feature'] - }, { - ...params, - outSR: undefined, - returnCountOnly: undefined - }]); + renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([ + { + features: ['filtered-feature'], + }, + { + ...params, + outSR: undefined, + returnCountOnly: undefined, + }, + ]); }); it('should return extent and count', () => { @@ -368,17 +354,14 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnExtentOnly: true, returnCountOnly: true }; @@ -386,12 +369,15 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual('count-or-extent'); renderCountAndExtentResponseSpy.callCount.should.equal(1); - renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([{ - features: ['filtered-feature'] - }, { - ...params, - outSR: undefined - }]); + renderCountAndExtentResponseSpy.firstCall.args.should.deepEqual([ + { + features: ['filtered-feature'], + }, + { + ...params, + outSR: undefined, + }, + ]); }); describe('should return ids only', () => { @@ -402,25 +388,22 @@ describe('query', () => { const queryHandler = proxyquire('./', { ...stub, './filter-and-transform': { - filterAndTransform: filterAndTransformSpy - } + filterAndTransform: filterAndTransformSpy, + }, }); const json = { type: 'FeatureCollection', features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnIdsOnly: true }; @@ -428,19 +411,22 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ objectIdFieldName: 'OBJECTID', - objectIds: [1138516379] + objectIds: [1138516379], }); }); it('should return ids with idField', () => { const filterAndTransformSpy = sinon.spy(function ({ metadata }) { - return { metadata, features: [{ attributes: { anIdProp: 1138516379 } }] }; + return { + metadata, + features: [{ attributes: { anIdProp: 1138516379 } }], + }; }); const queryHandler = proxyquire('./', { ...stub, './filter-and-transform': { - filterAndTransform: filterAndTransformSpy - } + filterAndTransform: filterAndTransformSpy, + }, }); const json = { type: 'FeatureCollection', @@ -448,17 +434,14 @@ describe('query', () => { features: [ { properties: { - anIdProp: 1138516379 + anIdProp: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { returnIdsOnly: true }; @@ -466,7 +449,7 @@ describe('query', () => { const result = queryHandler(json, params); result.should.deepEqual({ objectIdFieldName: 'anIdProp', - objectIds: [1138516379] + objectIds: [1138516379], }); }); }); @@ -477,39 +460,41 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const params = { - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], }; const result = queryHandler(json, params); result.should.deepEqual('out-statistics'); renderStatisticsResponseSpy.callCount.should.equal(1); - renderStatisticsResponseSpy.firstCall.args.should.deepEqual([{ - statistics: [{ fooStatistic: 1.234 }] - }, { - ...params, - geometryType: 'geometry-type', - attributeSample: { - OBJECTID: 1138516379 - } - }]); + renderStatisticsResponseSpy.firstCall.args.should.deepEqual([ + { + statistics: [{ fooStatistic: 1.234 }], + }, + { + ...params, + geometryType: 'geometry-type', + attributeSample: { + OBJECTID: 1138516379, + }, + }, + ]); }); it('should return feature response', () => { @@ -518,29 +503,29 @@ describe('query', () => { features: [ { properties: { - OBJECTID: 1138516379 + OBJECTID: 1138516379, }, geometry: { type: 'Point', - coordinates: [ - -104, - 40 - ] - } - } - ] + coordinates: [-104, 40], + }, + }, + ], }; const result = queryHandler(json); result.should.deepEqual('features'); renderFeaturesResponseSpy.callCount.should.equal(1); - renderFeaturesResponseSpy.firstCall.args.should.deepEqual([{ - features: ['filtered-feature'] - }, { - geometryType: 'geometry-type', - attributeSample: { - OBJECTID: 1138516379 - } - }]); + renderFeaturesResponseSpy.firstCall.args.should.deepEqual([ + { + features: ['filtered-feature'], + }, + { + geometryType: 'geometry-type', + attributeSample: { + OBJECTID: 1138516379, + }, + }, + ]); }); }); diff --git a/packages/featureserver/src/query/log-provider-data-warnings.js b/packages/featureserver/src/query/log-provider-data-warnings.js index a8c3c3c6e..8d1386092 100644 --- a/packages/featureserver/src/query/log-provider-data-warnings.js +++ b/packages/featureserver/src/query/log-provider-data-warnings.js @@ -3,8 +3,14 @@ const { getDataTypeFromValue } = require('../helpers'); const logManager = require('../log-manager'); function logProviderDataWarnings(geojson, requestParams) { - const { f, outFields = '*', returnCountOnly, returnExtentOnly, returnIdsOnly } = requestParams; - + const { + f, + outFields = '*', + returnCountOnly, + returnExtentOnly, + returnIdsOnly, + } = requestParams; + if (f === 'geojson' || returnCountOnly || returnExtentOnly || returnIdsOnly) { return; } @@ -27,9 +33,9 @@ function logProviderDataWarnings(geojson, requestParams) { if (metadata.fields && properties) { const fields = getFieldsDefinitionsForResponse(metadata.fields, outFields); - + compareFieldDefintionsToFeature(fields, properties); - + compareFeatureToFieldDefinitions(properties, fields); } } @@ -39,13 +45,16 @@ function hasMixedCaseObjectIdKey(idField = '') { } function getFieldsDefinitionsForResponse(fields, outFields) { - const outFieldsSet = (outFields === '*' || outFields === '') ? null : outFields.split(','); + const outFieldsSet = + outFields === '*' || outFields === '' ? null : outFields.split(','); if (!outFieldsSet) { return fields; } - return fields.filter(field => { - return outFieldsSet.includes(field.alias) || outFieldsSet.includes(field.name); + return fields.filter((field) => { + return ( + outFieldsSet.includes(field.alias) || outFieldsSet.includes(field.name) + ); }); } @@ -63,8 +72,10 @@ function compareFieldDefintionsToFeature(fieldDefinitions, featureProperties) { } function compareFeatureToFieldDefinitions(featureProperties, fieldDefinitions) { - Object.keys(featureProperties).forEach(key => { - const definition = _.find(fieldDefinitions, ['name', key]) || _.find(fieldDefinitions, ['name', key]); + Object.keys(featureProperties).forEach((key) => { + const definition = + _.find(fieldDefinitions, ['name', key]) || + _.find(fieldDefinitions, ['name', key]); if (!definition && key !== 'OBJECTID') { logManager.logger.debug( @@ -78,14 +89,16 @@ function findFeatureProperty(properties, name, alias) { return properties[name] || properties[alias]; } -function hasTypeMismatch (definitionType, value) { +function hasTypeMismatch(definitionType, value) { const propertyType = getDataTypeFromValue(value); - return definitionType !== propertyType && - !isEsriTypeMatchException(definitionType, propertyType); + return ( + definitionType !== propertyType && + !isEsriTypeMatchException(definitionType, propertyType) + ); } -function isEsriTypeMatchException (definitionType, propertyType) { +function isEsriTypeMatchException(definitionType, propertyType) { if (definitionType === 'Date' || definitionType === 'Double') { return propertyType === 'Integer'; } diff --git a/packages/featureserver/src/query/log-provider-data-warnings.spec.js b/packages/featureserver/src/query/log-provider-data-warnings.spec.js index bd2a921df..781115d29 100644 --- a/packages/featureserver/src/query/log-provider-data-warnings.spec.js +++ b/packages/featureserver/src/query/log-provider-data-warnings.spec.js @@ -5,13 +5,16 @@ const proxyquire = require('proxyquire'); describe('logProviderDataWarnings', () => { const loggerSpy = sinon.spy(() => {}); - const { logProviderDataWarnings } = proxyquire('./log-provider-data-warnings', { - '../log-manager': { - logger: { - debug: loggerSpy, + const { logProviderDataWarnings } = proxyquire( + './log-provider-data-warnings', + { + '../log-manager': { + logger: { + debug: loggerSpy, + }, }, }, - }); + ); afterEach(() => { loggerSpy.resetHistory(); @@ -34,10 +37,13 @@ describe('logProviderDataWarnings', () => { }); it('should log field definition not found in feature', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'String' }] }, - features: [{ properties: {} }], - }, {}); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'String' }] }, + features: [{ properties: {} }], + }, + {}, + ); loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ 'field definition "foo (String)" not found in first feature of provider\'s GeoJSON', @@ -45,11 +51,13 @@ describe('logProviderDataWarnings', () => { }); it('should log field definition - feature property type mismatch', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'String' }] }, - features: [{ properties: { foo: 1000 } }], - }, - { outFields: '' }); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'String' }] }, + features: [{ properties: { foo: 1000 } }], + }, + { outFields: '' }, + ); loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ 'field definition "foo (String)" not found in first feature of provider\'s GeoJSON', @@ -57,11 +65,13 @@ describe('logProviderDataWarnings', () => { }); it('should log field definition - feature property type mismatch (outFields as empty string)', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'String' }] }, - features: [{ properties: { foo: 1000 } }], - }, - {}); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'String' }] }, + features: [{ properties: { foo: 1000 } }], + }, + {}, + ); loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ 'field definition "foo (String)" not found in first feature of provider\'s GeoJSON', @@ -69,11 +79,13 @@ describe('logProviderDataWarnings', () => { }); it('should log field definition - feature property type mismatch (outFields defined)', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'String' }] }, - features: [{ properties: { foo: 1000 } }], - }, - { outFields: 'foo'}); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'String' }] }, + features: [{ properties: { foo: 1000 } }], + }, + { outFields: 'foo' }, + ); loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ @@ -82,12 +94,14 @@ describe('logProviderDataWarnings', () => { }); it('should log field definition - feature property type mismatch (outFields defined with alias)', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', alias: 'food', type: 'String' }] }, - features: [{ properties: { foo: 1000 } }], - }, - { outFields: 'food'}); - + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', alias: 'food', type: 'String' }] }, + features: [{ properties: { foo: 1000 } }], + }, + { outFields: 'food' }, + ); + loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ 'field definition "foo (String)" not found in first feature of provider\'s GeoJSON', @@ -95,26 +109,35 @@ describe('logProviderDataWarnings', () => { }); it('should not log warning if field definition matches feature', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'String' }] }, - features: [{ properties: { foo: 'bar' } }], - }, {}); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'String' }] }, + features: [{ properties: { foo: 'bar' } }], + }, + {}, + ); loggerSpy.callCount.should.equal(1); }); it('should not log warning if field type mismatch is Esri date exception', () => { - logProviderDataWarnings({ - metadata: { fields: [{ name: 'foo', type: 'Date' }] }, - features: [{ properties: { foo: 12345 } }], - }, {}); + logProviderDataWarnings( + { + metadata: { fields: [{ name: 'foo', type: 'Date' }] }, + features: [{ properties: { foo: 12345 } }], + }, + {}, + ); loggerSpy.callCount.should.equal(1); }); it('should log feature property not found in field definitions', () => { - logProviderDataWarnings({ - metadata: { fields: [] }, - features: [{ properties: { foo: 'bar' } }], - }, {}); + logProviderDataWarnings( + { + metadata: { fields: [] }, + features: [{ properties: { foo: 'bar' } }], + }, + {}, + ); loggerSpy.callCount.should.equal(2); loggerSpy.secondCall.args.should.deepEqual([ 'requested provider has feature with property "foo" that was not defined in metadata fields array', diff --git a/packages/featureserver/src/query/render-count-and-extent.js b/packages/featureserver/src/query/render-count-and-extent.js index 580f89eba..74575e462 100644 --- a/packages/featureserver/src/query/render-count-and-extent.js +++ b/packages/featureserver/src/query/render-count-and-extent.js @@ -1,28 +1,24 @@ const _ = require('lodash'); const esriExtent = require('esri-extent'); -function renderCountAndExtentResponse (data, params) { - const { - returnCountOnly, - returnExtentOnly, - outSR - } = params; +function renderCountAndExtentResponse(data, params) { + const { returnCountOnly, returnExtentOnly, outSR } = params; if (returnCountOnly && returnExtentOnly) { return { count: _.get(data, 'features.length', 0), - extent: getExtent(data, outSR) + extent: getExtent(data, outSR), }; } if (returnCountOnly) { return { - count: _.get(data, 'features.length', 0) + count: _.get(data, 'features.length', 0), }; } return { - extent: getExtent(data, outSR) + extent: getExtent(data, outSR), }; } @@ -31,7 +27,7 @@ function renderCountAndExtentResponse (data, params) { * @param {object} geojson * @param {*} outSR Esri spatial reference object, or WKID integer */ -function getExtent (geojson, outSR) { +function getExtent(geojson, outSR) { // Calculate extent from features const extent = esriExtent(geojson); diff --git a/packages/featureserver/src/query/render-count-and-extent.spec.js b/packages/featureserver/src/query/render-count-and-extent.spec.js index aa00e33d5..17dd65574 100644 --- a/packages/featureserver/src/query/render-count-and-extent.spec.js +++ b/packages/featureserver/src/query/render-count-and-extent.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const sinon = require('sinon'); const proxyquire = require('proxyquire'); @@ -7,16 +7,19 @@ const esriExtentSpy = sinon.spy(function () { foo: 'bar', spatialReference: { wkid: 4326, - latestWkid: 4326 - } + latestWkid: 4326, + }, }; }); const stub = { - 'esri-extent': esriExtentSpy + 'esri-extent': esriExtentSpy, }; -const { renderCountAndExtentResponse } = proxyquire('./render-count-and-extent', stub); +const { renderCountAndExtentResponse } = proxyquire( + './render-count-and-extent', + stub, +); describe('renderCountAndExtent', () => { afterEach(function () { @@ -24,123 +27,150 @@ describe('renderCountAndExtent', () => { }); it('should render count and extent', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnCountOnly: true, returnExtentOnly: true }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnCountOnly: true, returnExtentOnly: true }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { wkid: 4326, - latestWkid: 4326 - } + latestWkid: 4326, + }, }, - count: 1 + count: 1, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render count', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnCountOnly: true }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnCountOnly: true }, + ); result.should.deepEqual({ - count: 1 + count: 1, }); esriExtentSpy.callCount.should.equal(0); }); it('should render extent', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { wkid: 4326, - latestWkid: 4326 - } - } + latestWkid: 4326, + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR wkid', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: { wkid: 1234 } }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: { wkid: 1234 } }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - wkid: 1234 - } - } + wkid: 1234, + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR latestWkid', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: { latestWkid: 1234 } }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: { latestWkid: 1234 } }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - latestWkid: 1234 - } - } + latestWkid: 1234, + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR wkt', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: { wkt: '1234' } }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: { wkt: '1234' } }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - wkt: '1234' - } - } + wkt: '1234', + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR id', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: 1234 }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: 1234 }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - wkid: 1234 - } - } + wkid: 1234, + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR string id', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: '1234' }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: '1234' }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - wkid: 1234 - } - } + wkid: 1234, + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); }); it('should render extent and replace spatialReference with outSR string', () => { - const result = renderCountAndExtentResponse({ features: ['test'] }, { returnExtentOnly: true, outSR: 'big-WKT-string' }); + const result = renderCountAndExtentResponse( + { features: ['test'] }, + { returnExtentOnly: true, outSR: 'big-WKT-string' }, + ); result.should.deepEqual({ extent: { foo: 'bar', spatialReference: { - wkt: 'big-WKT-string' - } - } + wkt: 'big-WKT-string', + }, + }, }); esriExtentSpy.callCount.should.equal(1); esriExtentSpy.firstCall.args.should.deepEqual([{ features: ['test'] }]); diff --git a/packages/featureserver/src/query/render-features.spec.js b/packages/featureserver/src/query/render-features.spec.js index e0971eabe..4d9ecbe9c 100644 --- a/packages/featureserver/src/query/render-features.spec.js +++ b/packages/featureserver/src/query/render-features.spec.js @@ -227,7 +227,7 @@ describe('renderFeaturesResponse', () => { const getCollectionCrsSpy = sinon.spy(function () { return; }); - + const stub = { '../helpers/fields': fields, '../helpers': { @@ -398,11 +398,11 @@ describe('renderFeaturesResponse', () => { const normalizeSpatialReferenceSpy = sinon.spy(function (latestWkid) { return { latestWkid }; }); - + const getCollectionCrsSpy = sinon.spy(function () { return 'crs'; }); - + const stub = { '../helpers/fields': fields, '../helpers': { @@ -410,7 +410,7 @@ describe('renderFeaturesResponse', () => { normalizeSpatialReference: normalizeSpatialReferenceSpy, }, }; - + const { renderFeaturesResponse } = proxyquire('./render-features', stub); const result = renderFeaturesResponse(json, { geometryType: 'esriGeometryPoint', @@ -445,11 +445,11 @@ describe('renderFeaturesResponse', () => { const normalizeSpatialReferenceSpy = sinon.spy(function (latestWkid) { return { wkid: latestWkid, latestWkid }; }); - + const getCollectionCrsSpy = sinon.spy(function () { return 'crs'; }); - + const stub = { '../helpers/fields': fields, '../helpers': { @@ -457,7 +457,7 @@ describe('renderFeaturesResponse', () => { normalizeSpatialReference: normalizeSpatialReferenceSpy, }, }; - + const { renderFeaturesResponse } = proxyquire('./render-features', stub); const result = renderFeaturesResponse(json, { geometryType: 'esriGeometryPoint', @@ -493,11 +493,11 @@ describe('renderFeaturesResponse', () => { const normalizeSpatialReferenceSpy = sinon.spy(function (wkt) { return { wkt }; }); - + const getCollectionCrsSpy = sinon.spy(function () { return 'crs'; }); - + const stub = { '../helpers/fields': fields, '../helpers': { @@ -505,7 +505,7 @@ describe('renderFeaturesResponse', () => { normalizeSpatialReference: normalizeSpatialReferenceSpy, }, }; - + const { renderFeaturesResponse } = proxyquire('./render-features', stub); const result = renderFeaturesResponse(json, { geometryType: 'esriGeometryPoint', @@ -533,7 +533,9 @@ describe('renderFeaturesResponse', () => { }); getCollectionCrsSpy.callCount.should.equal(0); normalizeSpatialReferenceSpy.callCount.should.equal(1); - normalizeSpatialReferenceSpy.firstCall.args.should.deepEqual(['wkt-here']); + normalizeSpatialReferenceSpy.firstCall.args.should.deepEqual([ + 'wkt-here', + ]); }); }); }); diff --git a/packages/featureserver/src/query/render-precalculated-statistics.js b/packages/featureserver/src/query/render-precalculated-statistics.js index 3a89abbfe..61133c1ee 100644 --- a/packages/featureserver/src/query/render-precalculated-statistics.js +++ b/packages/featureserver/src/query/render-precalculated-statistics.js @@ -1,37 +1,35 @@ const _ = require('lodash'); // const { isValidISODateString, isValidDate } = require('iso-datestring-validator'); -const { - StatisticsFields -} = require('../helpers/fields'); +const { StatisticsFields } = require('../helpers/fields'); const { isDate } = require('../helpers/data-type-utils'); -function renderPrecalculatedStatisticsResponse (input, options) { - const { - statistics - } = input; +function renderPrecalculatedStatisticsResponse(input, options) { + const { statistics } = input; - const normalizedStatistics = Array.isArray(statistics) ? statistics : [statistics]; + const normalizedStatistics = Array.isArray(statistics) + ? statistics + : [statistics]; const fields = StatisticsFields.create({ ...input, - ...options + ...options, }); return { fields, - features: createStatisticFeatures(normalizedStatistics) + features: createStatisticFeatures(normalizedStatistics), }; } -function createStatisticFeatures (statistics) { - return statistics.map(statistic => { +function createStatisticFeatures(statistics) { + return statistics.map((statistic) => { return { - attributes: convertDatePropertiesToTimestamps(statistic) + attributes: convertDatePropertiesToTimestamps(statistic), }; }); } -function convertDatePropertiesToTimestamps (obj) { - return _.mapValues(obj, value => { +function convertDatePropertiesToTimestamps(obj) { + return _.mapValues(obj, (value) => { if (isDate(value)) { return new Date(value).getTime(); } diff --git a/packages/featureserver/src/query/render-precalculated-statistics.spec.js b/packages/featureserver/src/query/render-precalculated-statistics.spec.js index e2b27cf56..625bbef75 100644 --- a/packages/featureserver/src/query/render-precalculated-statistics.spec.js +++ b/packages/featureserver/src/query/render-precalculated-statistics.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const sinon = require('sinon'); const proxyquire = require('proxyquire'); @@ -8,15 +8,18 @@ const createStatisticsFieldsSpy = sinon.spy(function () { const fields = { StatisticsFields: { - create: createStatisticsFieldsSpy - } + create: createStatisticsFieldsSpy, + }, }; const stub = { - '../helpers/fields': fields + '../helpers/fields': fields, }; -const { renderPrecalculatedStatisticsResponse } = proxyquire('./render-precalculated-statistics', stub); +const { renderPrecalculatedStatisticsResponse } = proxyquire( + './render-precalculated-statistics', + stub, +); describe('renderPrecalculatedStatisticsResponse', () => { afterEach(function () { @@ -30,15 +33,15 @@ describe('renderPrecalculatedStatisticsResponse', () => { TOTAL_STUD_SUM: 5421, ZIP_CODE_COUNT: 18, SOME_DATE_STRING: '2020-12-01', - SOME_ISO_DATE_STRING: '2020-12-01T17:00:14.000Z' + SOME_ISO_DATE_STRING: '2020-12-01T17:00:14.000Z', }, { FACUSE: 'Elementary School', TOTAL_STUD_SUM: 23802, ZIP_CODE_COUNT: 72, SOME_DATE_STRING: '2020-12-01', - SOME_ISO_DATE_STRING: '2020-12-01T17:00:14.000Z' - } + SOME_ISO_DATE_STRING: '2020-12-01T17:00:14.000Z', + }, ]; const result = renderPrecalculatedStatisticsResponse({ statistics }); result.should.deepEqual({ @@ -50,8 +53,8 @@ describe('renderPrecalculatedStatisticsResponse', () => { TOTAL_STUD_SUM: 5421, ZIP_CODE_COUNT: 18, SOME_DATE_STRING: 1606780800000, - SOME_ISO_DATE_STRING: 1606842014000 - } + SOME_ISO_DATE_STRING: 1606842014000, + }, }, { attributes: { @@ -59,10 +62,10 @@ describe('renderPrecalculatedStatisticsResponse', () => { TOTAL_STUD_SUM: 23802, ZIP_CODE_COUNT: 72, SOME_DATE_STRING: 1606780800000, - SOME_ISO_DATE_STRING: 1606842014000 - } - } - ] + SOME_ISO_DATE_STRING: 1606842014000, + }, + }, + ], }); createStatisticsFieldsSpy.callCount.should.equal(1); }); @@ -71,7 +74,7 @@ describe('renderPrecalculatedStatisticsResponse', () => { const statistics = { FACUSE: 'Middle School', TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 + ZIP_CODE_COUNT: 18, }; const result = renderPrecalculatedStatisticsResponse({ statistics }); result.should.deepEqual({ @@ -81,10 +84,10 @@ describe('renderPrecalculatedStatisticsResponse', () => { attributes: { FACUSE: 'Middle School', TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 - } - } - ] + ZIP_CODE_COUNT: 18, + }, + }, + ], }); createStatisticsFieldsSpy.callCount.should.equal(1); }); diff --git a/packages/featureserver/src/query/render-statistics.js b/packages/featureserver/src/query/render-statistics.js index b002f98d5..86cde1749 100644 --- a/packages/featureserver/src/query/render-statistics.js +++ b/packages/featureserver/src/query/render-statistics.js @@ -1,23 +1,23 @@ -const { - StatisticsFields -} = require('../helpers/fields'); +const { StatisticsFields } = require('../helpers/fields'); -function renderStatisticsResponse (input = {}, options = {}) { +function renderStatisticsResponse(input = {}, options = {}) { const { statistics } = input; - const normalizedStatistics = Array.isArray(statistics) ? statistics : [statistics]; - const features = normalizedStatistics.map(attributes => { + const normalizedStatistics = Array.isArray(statistics) + ? statistics + : [statistics]; + const features = normalizedStatistics.map((attributes) => { return { attributes }; }); const fields = StatisticsFields.create({ statistics, - ...options + ...options, }); return { displayFieldName: '', fields, - features + features, }; } diff --git a/packages/featureserver/src/query/render-statistics.spec.js b/packages/featureserver/src/query/render-statistics.spec.js index 053dbf6f1..1503ba56e 100644 --- a/packages/featureserver/src/query/render-statistics.spec.js +++ b/packages/featureserver/src/query/render-statistics.spec.js @@ -1,20 +1,22 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const sinon = require('sinon'); const proxyquire = require('proxyquire'); const createStatisticsFieldsSpy = sinon.spy(function () { - return [{ - foo: 'bar' - }]; + return [ + { + foo: 'bar', + }, + ]; }); const fields = { StatisticsFields: { - create: createStatisticsFieldsSpy - } + create: createStatisticsFieldsSpy, + }, }; const stub = { - '../helpers/fields': fields + '../helpers/fields': fields, }; const { renderStatisticsResponse } = proxyquire('./render-statistics', stub); @@ -25,70 +27,88 @@ describe('renderStatisticsResponse', () => { }); it('should convert statistics array to Geoservices JSON', () => { - const result = renderStatisticsResponse({ statistics: [{ min_precip: 0 }] }, { - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] - }); + const result = renderStatisticsResponse( + { statistics: [{ min_precip: 0 }] }, + { + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], + }, + ); result.should.deepEqual({ displayFieldName: '', - fields: [{ - foo: 'bar' - }], + fields: [ + { + foo: 'bar', + }, + ], features: [ { attributes: { - min_precip: 0 - } - } - ] + min_precip: 0, + }, + }, + ], }); createStatisticsFieldsSpy.callCount.should.equal(1); createStatisticsFieldsSpy.firstCall.args.should.deepEqual([ { statistics: [{ min_precip: 0 }], - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] - } + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], + }, ]); }); it('should convert statistics object to Geoservices JSON', () => { - const result = renderStatisticsResponse({ statistics: { min_precip: 0 } }, { - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] - }); + const result = renderStatisticsResponse( + { statistics: { min_precip: 0 } }, + { + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], + }, + ); result.should.deepEqual({ displayFieldName: '', - fields: [{ - foo: 'bar' - }], + fields: [ + { + foo: 'bar', + }, + ], features: [ { attributes: { - min_precip: 0 - } - } - ] + min_precip: 0, + }, + }, + ], }); createStatisticsFieldsSpy.callCount.should.equal(1); createStatisticsFieldsSpy.firstCall.args.should.deepEqual([ { statistics: { min_precip: 0 }, - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] - } + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], + }, ]); }); }); diff --git a/packages/featureserver/src/query/validate-query-request-parameters.js b/packages/featureserver/src/query/validate-query-request-parameters.js index 155957580..74fb97329 100644 --- a/packages/featureserver/src/query/validate-query-request-parameters.js +++ b/packages/featureserver/src/query/validate-query-request-parameters.js @@ -1,9 +1,11 @@ const joi = require('joi'); -const spatialReferenceSchema = joi.object({ - wkid: joi.number().integer().required(), - latestWkid: joi.number().integer(), -}).unknown(); +const spatialReferenceSchema = joi + .object({ + wkid: joi.number().integer().required(), + latestWkid: joi.number().integer(), + }) + .unknown(); const esriExtentSchema = joi.object({ xmin: joi.number().required(), @@ -20,10 +22,11 @@ const quantizationParametersSchema = joi.object({ mode: joi.string().optional(), }); - -const queryRequestSchema = joi.object({ - quantizationParameters: quantizationParametersSchema -}).unknown(); +const queryRequestSchema = joi + .object({ + quantizationParameters: quantizationParametersSchema, + }) + .unknown(); function validate(queryRequestParams) { const { error } = queryRequestSchema.validate(queryRequestParams); @@ -37,7 +40,7 @@ function handleError(error) { // TODO: right now the only possible error is for quantizationParams // const [param] = error.details[0].path; // if (param === 'quantizationParameters') { - const err = new Error('\'quantizationParameters\' parameter is invalid'); + const err = new Error("'quantizationParameters' parameter is invalid"); err.code = 400; err.details = [error.details[0].message]; throw err; @@ -45,5 +48,5 @@ function handleError(error) { // throw error; } module.exports = { - validate + validate, }; diff --git a/packages/featureserver/src/query/validate-query-request-parameters.spec.js b/packages/featureserver/src/query/validate-query-request-parameters.spec.js index d87628c64..23918c9cf 100644 --- a/packages/featureserver/src/query/validate-query-request-parameters.spec.js +++ b/packages/featureserver/src/query/validate-query-request-parameters.spec.js @@ -12,10 +12,10 @@ describe('validate-query-request-parameters', () => { }); } catch (error) { error.message.should.deepEqual( - '\'quantizationParameters\' parameter is invalid', + "'quantizationParameters' parameter is invalid", ); error.details.should.deepEqual([ - '"quantizationParameters.extent.xmin" is required' + '"quantizationParameters.extent.xmin" is required', ]); error.code.should.equal(400); } diff --git a/packages/featureserver/src/queryRelatedRecords.js b/packages/featureserver/src/queryRelatedRecords.js index 4a8335b88..1e636e57c 100644 --- a/packages/featureserver/src/queryRelatedRecords.js +++ b/packages/featureserver/src/queryRelatedRecords.js @@ -1,17 +1,16 @@ const _ = require('lodash'); const { getCollectionCrs, getGeometryTypeFromGeojson } = require('./helpers'); -const { - QueryFields -} = require('./helpers/fields'); +const { QueryFields } = require('./helpers/fields'); module.exports = queryRelatedRecords; -function queryRelatedRecords (data, params = {}) { +function queryRelatedRecords(data, params = {}) { const response = { - relatedRecordGroups: [] + relatedRecordGroups: [], }; - if (!params.returnCountOnly) response.fields = QueryFields.create({ ...data, ...params }); + if (!params.returnCountOnly) + response.fields = QueryFields.create({ ...data, ...params }); const geomType = getGeometryTypeFromGeojson(data); if (geomType) { @@ -22,17 +21,23 @@ function queryRelatedRecords (data, params = {}) { } if (data.features) { - response.relatedRecordGroups = data.features.map(featureCollection => { - return convertFeaturesToRelatedRecordGroups(featureCollection, params.returnCountOnly); + response.relatedRecordGroups = data.features.map((featureCollection) => { + return convertFeaturesToRelatedRecordGroups( + featureCollection, + params.returnCountOnly, + ); }); } return response; } -function convertFeaturesToRelatedRecordGroups ({ features, properties }, returnCountOnly = false) { +function convertFeaturesToRelatedRecordGroups( + { features, properties }, + returnCountOnly = false, +) { const recordGroup = { - objectId: properties.objectid + objectId: properties.objectid, }; if (returnCountOnly) { @@ -50,7 +55,7 @@ function convertFeaturesToRelatedRecordGroups ({ features, properties }, returnC recordGroup.relatedRecords = features.map(({ geometry, properties }) => { return { attributes: properties, - geometry: geometry + geometry: geometry, }; }); } diff --git a/packages/featureserver/src/response-handlers/general-response-handler.js b/packages/featureserver/src/response-handlers/general-response-handler.js index b9d59648f..c3f23520a 100644 --- a/packages/featureserver/src/response-handlers/general-response-handler.js +++ b/packages/featureserver/src/response-handlers/general-response-handler.js @@ -1,6 +1,10 @@ const { sendCallbackResponse, sendPrettyJson } = require('./helpers'); -module.exports = function generalResponseHandler(res, payload, requestParameters) { +module.exports = function generalResponseHandler( + res, + payload, + requestParameters, +) { const { f, callback } = requestParameters; if (typeof callback === 'string') { diff --git a/packages/featureserver/src/response-handlers/general-response-handler.spec.js b/packages/featureserver/src/response-handlers/general-response-handler.spec.js index c21597c1b..255479f0e 100644 --- a/packages/featureserver/src/response-handlers/general-response-handler.spec.js +++ b/packages/featureserver/src/response-handlers/general-response-handler.spec.js @@ -73,9 +73,6 @@ describe('general response handler', () => { }, ); - sendPrettyJsonSpy.firstCall.args.should.deepEqual([ - res, - { test: true } - ]); + sendPrettyJsonSpy.firstCall.args.should.deepEqual([res, { test: true }]); }); }); diff --git a/packages/featureserver/src/response-handlers/helpers/index.js b/packages/featureserver/src/response-handlers/helpers/index.js index 138c6286e..52fbcdc1b 100644 --- a/packages/featureserver/src/response-handlers/helpers/index.js +++ b/packages/featureserver/src/response-handlers/helpers/index.js @@ -1,5 +1,5 @@ module.exports = { ...require('./send-pbf/index.js'), ...require('./send-callback.js'), - ...require('./send-pretty-json.js') + ...require('./send-pretty-json.js'), }; diff --git a/packages/featureserver/src/response-handlers/helpers/send-callback.js b/packages/featureserver/src/response-handlers/helpers/send-callback.js index c8933cb13..484a45d7d 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-callback.js +++ b/packages/featureserver/src/response-handlers/helpers/send-callback.js @@ -1,9 +1,9 @@ function sendCallbackResponse(res, payload, callbackString) { - const sanitizedCallback = callbackString.replace(/[^\w\d\.\(\)\[\]]/g, '') // eslint-disable-line + const sanitizedCallback = callbackString.replace(/[^\w\d\.\(\)\[\]]/g, ''); res.set('Content-Type', 'application/javascript'); res.status(200); return res.send(`${sanitizedCallback}(${JSON.stringify(payload)})`); } module.exports = { - sendCallbackResponse + sendCallbackResponse, }; diff --git a/packages/featureserver/src/response-handlers/helpers/send-callback.spec.js b/packages/featureserver/src/response-handlers/helpers/send-callback.spec.js index 60fb923ed..6f73b22e8 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-callback.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-callback.spec.js @@ -2,7 +2,6 @@ const should = require('should'); // eslint-disable-line const sinon = require('sinon'); const { sendCallbackResponse } = require('./'); - const res = { set: sinon.spy(() => { return res; @@ -10,14 +9,17 @@ const res = { status: sinon.spy(() => { return res; }), - send: sinon.spy() + send: sinon.spy(), }; describe('sendCallbackResponse', () => { it('should respond with callback string', () => { - sendCallbackResponse(res, { hello: 'world'}, 'what'); - res.set.firstCall.args.should.deepEqual(['Content-Type', 'application/javascript']); + sendCallbackResponse(res, { hello: 'world' }, 'what'); + res.set.firstCall.args.should.deepEqual([ + 'Content-Type', + 'application/javascript', + ]); res.send.firstCall.args[0].should.equal('what({"hello":"world"})'); res.status.firstCall.args[0].should.be.exactly(200); }); -}); \ No newline at end of file +}); diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/FeatureCollection.proto.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/FeatureCollection.proto.js index 168eccd13..df3c634b2 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/FeatureCollection.proto.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/FeatureCollection.proto.js @@ -1,2964 +1,4004 @@ // TODO: move this to a npm -/* eslint-disable */ -/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/ -"use strict"; +'use strict'; -var $protobuf = require("protobufjs/minimal"); +var $protobuf = require('protobufjs/minimal'); -var $Writer = $protobuf.Writer, $util = $protobuf.util; +var $Writer = $protobuf.Writer, + $util = $protobuf.util; -var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); +var $root = $protobuf.roots['default'] || ($protobuf.roots['default'] = {}); -$root.esriPBuffer = (function() { +$root.esriPBuffer = (function () { + var esriPBuffer = {}; - var esriPBuffer = {}; + esriPBuffer.FeatureCollectionPBuffer = (function () { + function FeatureCollectionPBuffer(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) this[keys[i]] = properties[keys[i]]; + } - esriPBuffer.FeatureCollectionPBuffer = (function() { + FeatureCollectionPBuffer.prototype.version = ''; + FeatureCollectionPBuffer.prototype.queryResult = null; - function FeatureCollectionPBuffer(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.create = function create(properties) { + return new FeatureCollectionPBuffer(properties); + }; - FeatureCollectionPBuffer.prototype.version = ""; - FeatureCollectionPBuffer.prototype.queryResult = null; + FeatureCollectionPBuffer.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.version != null && + Object.hasOwnProperty.call(message, 'version') + ) + writer.uint32(10).string(message.version); + if ( + message.queryResult != null && + Object.hasOwnProperty.call(message, 'queryResult') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.encode( + message.queryResult, + writer.uint32(18).fork(), + ).ldelim(); + return writer; + }; - FeatureCollectionPBuffer.create = function create(properties) { - return new FeatureCollectionPBuffer(properties); - }; + FeatureCollectionPBuffer.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; - FeatureCollectionPBuffer.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.version != null && Object.hasOwnProperty.call(message, "version")) - writer.uint32(10).string(message.version); - if (message.queryResult != null && Object.hasOwnProperty.call(message, "queryResult")) - $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.encode(message.queryResult, writer.uint32(18).fork()).ldelim(); - return writer; - }; + FeatureCollectionPBuffer.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.version != null && message.hasOwnProperty('version')) + if (!$util.isString(message.version)) return 'version: string expected'; + if ( + message.queryResult != null && + message.hasOwnProperty('queryResult') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.verify( + message.queryResult, + ); + if (error) return 'queryResult.' + error; + } + return null; + }; - FeatureCollectionPBuffer.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; + FeatureCollectionPBuffer.fromObject = function fromObject(object) { + if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer(); + if (object.version != null) message.version = String(object.version); + if (object.queryResult != null) { + if (typeof object.queryResult !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.queryResult: object expected', + ); + message.queryResult = + $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.fromObject( + object.queryResult, + ); + } + return message; + }; - FeatureCollectionPBuffer.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.version != null && message.hasOwnProperty("version")) - if (!$util.isString(message.version)) - return "version: string expected"; - if (message.queryResult != null && message.hasOwnProperty("queryResult")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.verify(message.queryResult); - if (error) - return "queryResult." + error; - } - return null; - }; - - FeatureCollectionPBuffer.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer(); - if (object.version != null) - message.version = String(object.version); - if (object.queryResult != null) { - if (typeof object.queryResult !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.queryResult: object expected"); - message.queryResult = $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.fromObject(object.queryResult); - } - return message; - }; - - FeatureCollectionPBuffer.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.version = ""; - object.queryResult = null; - } - if (message.version != null && message.hasOwnProperty("version")) - object.version = message.version; - if (message.queryResult != null && message.hasOwnProperty("queryResult")) - object.queryResult = $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.toObject(message.queryResult, options); - return object; - }; - - FeatureCollectionPBuffer.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - FeatureCollectionPBuffer.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer"; - }; - - FeatureCollectionPBuffer.GeometryType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "esriGeometryTypePoint"] = 0; - values[valuesById[1] = "esriGeometryTypeMultipoint"] = 1; - values[valuesById[2] = "esriGeometryTypePolyline"] = 2; - values[valuesById[3] = "esriGeometryTypePolygon"] = 3; - values[valuesById[4] = "esriGeometryTypeMultipatch"] = 4; - values[valuesById[127] = "esriGeometryTypeNone"] = 127; - values[valuesById[5] = "esriGeometryTypeEnvelope"] = 5; - return values; - })(); - - FeatureCollectionPBuffer.FieldType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "esriFieldTypeSmallInteger"] = 0; - values[valuesById[1] = "esriFieldTypeInteger"] = 1; - values[valuesById[2] = "esriFieldTypeSingle"] = 2; - values[valuesById[3] = "esriFieldTypeDouble"] = 3; - values[valuesById[4] = "esriFieldTypeString"] = 4; - values[valuesById[5] = "esriFieldTypeDate"] = 5; - values[valuesById[6] = "esriFieldTypeOID"] = 6; - values[valuesById[7] = "esriFieldTypeGeometry"] = 7; - values[valuesById[8] = "esriFieldTypeBlob"] = 8; - values[valuesById[9] = "esriFieldTypeRaster"] = 9; - values[valuesById[10] = "esriFieldTypeGUID"] = 10; - values[valuesById[11] = "esriFieldTypeGlobalID"] = 11; - values[valuesById[12] = "esriFieldTypeXML"] = 12; - values[valuesById[13] = "esriFieldTypeBigInteger"] = 13; - values[valuesById[14] = "esriFieldTypeDateOnly"] = 14; - values[valuesById[15] = "esriFieldTypeTimeOnly"] = 15; - values[valuesById[16] = "esriFieldTypeTimestampOffset"] = 16; - return values; - })(); - - FeatureCollectionPBuffer.SQLType = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "sqlTypeBigInt"] = 0; - values[valuesById[1] = "sqlTypeBinary"] = 1; - values[valuesById[2] = "sqlTypeBit"] = 2; - values[valuesById[3] = "sqlTypeChar"] = 3; - values[valuesById[4] = "sqlTypeDate"] = 4; - values[valuesById[5] = "sqlTypeDecimal"] = 5; - values[valuesById[6] = "sqlTypeDouble"] = 6; - values[valuesById[7] = "sqlTypeFloat"] = 7; - values[valuesById[8] = "sqlTypeGeometry"] = 8; - values[valuesById[9] = "sqlTypeGUID"] = 9; - values[valuesById[10] = "sqlTypeInteger"] = 10; - values[valuesById[11] = "sqlTypeLongNVarchar"] = 11; - values[valuesById[12] = "sqlTypeLongVarbinary"] = 12; - values[valuesById[13] = "sqlTypeLongVarchar"] = 13; - values[valuesById[14] = "sqlTypeNChar"] = 14; - values[valuesById[15] = "sqlTypeNVarchar"] = 15; - values[valuesById[16] = "sqlTypeOther"] = 16; - values[valuesById[17] = "sqlTypeReal"] = 17; - values[valuesById[18] = "sqlTypeSmallInt"] = 18; - values[valuesById[19] = "sqlTypeSqlXml"] = 19; - values[valuesById[20] = "sqlTypeTime"] = 20; - values[valuesById[21] = "sqlTypeTimestamp"] = 21; - values[valuesById[22] = "sqlTypeTimestamp2"] = 22; - values[valuesById[23] = "sqlTypeTinyInt"] = 23; - values[valuesById[24] = "sqlTypeVarbinary"] = 24; - values[valuesById[25] = "sqlTypeVarchar"] = 25; - values[valuesById[26] = "sqlTypeTimestampWithTimezone"] = 26; - return values; - })(); - - FeatureCollectionPBuffer.QuantizeOriginPostion = (function() { - var valuesById = {}, values = Object.create(valuesById); - values[valuesById[0] = "upperLeft"] = 0; - values[valuesById[1] = "lowerLeft"] = 1; - return values; - })(); - - FeatureCollectionPBuffer.SpatialReference = (function() { - - function SpatialReference(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.version = ''; + object.queryResult = null; + } + if (message.version != null && message.hasOwnProperty('version')) + object.version = message.version; + if (message.queryResult != null && message.hasOwnProperty('queryResult')) + object.queryResult = + $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult.toObject( + message.queryResult, + options, + ); + return object; + }; - SpatialReference.prototype.wkid = 0; - SpatialReference.prototype.lastestWkid = 0; - SpatialReference.prototype.vcsWkid = 0; - SpatialReference.prototype.latestVcsWkid = 0; - SpatialReference.prototype.wkt = ""; - - SpatialReference.create = function create(properties) { - return new SpatialReference(properties); - }; - - SpatialReference.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.wkid != null && Object.hasOwnProperty.call(message, "wkid")) - writer.uint32(8).uint32(message.wkid); - if (message.lastestWkid != null && Object.hasOwnProperty.call(message, "lastestWkid")) - writer.uint32(16).uint32(message.lastestWkid); - if (message.vcsWkid != null && Object.hasOwnProperty.call(message, "vcsWkid")) - writer.uint32(24).uint32(message.vcsWkid); - if (message.latestVcsWkid != null && Object.hasOwnProperty.call(message, "latestVcsWkid")) - writer.uint32(32).uint32(message.latestVcsWkid); - if (message.wkt != null && Object.hasOwnProperty.call(message, "wkt")) - writer.uint32(42).string(message.wkt); - return writer; - }; - - SpatialReference.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - SpatialReference.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.wkid != null && message.hasOwnProperty("wkid")) - if (!$util.isInteger(message.wkid)) - return "wkid: integer expected"; - if (message.lastestWkid != null && message.hasOwnProperty("lastestWkid")) - if (!$util.isInteger(message.lastestWkid)) - return "lastestWkid: integer expected"; - if (message.vcsWkid != null && message.hasOwnProperty("vcsWkid")) - if (!$util.isInteger(message.vcsWkid)) - return "vcsWkid: integer expected"; - if (message.latestVcsWkid != null && message.hasOwnProperty("latestVcsWkid")) - if (!$util.isInteger(message.latestVcsWkid)) - return "latestVcsWkid: integer expected"; - if (message.wkt != null && message.hasOwnProperty("wkt")) - if (!$util.isString(message.wkt)) - return "wkt: string expected"; - return null; - }; - - SpatialReference.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference(); - if (object.wkid != null) - message.wkid = object.wkid >>> 0; - if (object.lastestWkid != null) - message.lastestWkid = object.lastestWkid >>> 0; - if (object.vcsWkid != null) - message.vcsWkid = object.vcsWkid >>> 0; - if (object.latestVcsWkid != null) - message.latestVcsWkid = object.latestVcsWkid >>> 0; - if (object.wkt != null) - message.wkt = String(object.wkt); - return message; - }; - - SpatialReference.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.wkid = 0; - object.lastestWkid = 0; - object.vcsWkid = 0; - object.latestVcsWkid = 0; - object.wkt = ""; - } - if (message.wkid != null && message.hasOwnProperty("wkid")) - object.wkid = message.wkid; - if (message.lastestWkid != null && message.hasOwnProperty("lastestWkid")) - object.lastestWkid = message.lastestWkid; - if (message.vcsWkid != null && message.hasOwnProperty("vcsWkid")) - object.vcsWkid = message.vcsWkid; - if (message.latestVcsWkid != null && message.hasOwnProperty("latestVcsWkid")) - object.latestVcsWkid = message.latestVcsWkid; - if (message.wkt != null && message.hasOwnProperty("wkt")) - object.wkt = message.wkt; - return object; - }; - - SpatialReference.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - SpatialReference.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.SpatialReference"; - }; - - return SpatialReference; - })(); - - FeatureCollectionPBuffer.Field = (function() { - - function Field(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + FeatureCollectionPBuffer.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer'; + }; - Field.prototype.name = ""; - Field.prototype.fieldType = 0; - Field.prototype.alias = ""; - Field.prototype.sqlType = 0; - Field.prototype.domain = ""; - Field.prototype.defaultValue = ""; - - Field.create = function create(properties) { - return new Field(properties); - }; - - Field.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(10).string(message.name); - if (message.fieldType != null && Object.hasOwnProperty.call(message, "fieldType")) - writer.uint32(16).int32(message.fieldType); - if (message.alias != null && Object.hasOwnProperty.call(message, "alias")) - writer.uint32(26).string(message.alias); - if (message.sqlType != null && Object.hasOwnProperty.call(message, "sqlType")) - writer.uint32(32).int32(message.sqlType); - if (message.domain != null && Object.hasOwnProperty.call(message, "domain")) - writer.uint32(42).string(message.domain); - if (message.defaultValue != null && Object.hasOwnProperty.call(message, "defaultValue")) - writer.uint32(50).string(message.defaultValue); - return writer; - }; - - Field.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Field.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - if (message.fieldType != null && message.hasOwnProperty("fieldType")) - switch (message.fieldType) { - default: - return "fieldType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - break; - } - if (message.alias != null && message.hasOwnProperty("alias")) - if (!$util.isString(message.alias)) - return "alias: string expected"; - if (message.sqlType != null && message.hasOwnProperty("sqlType")) - switch (message.sqlType) { - default: - return "sqlType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - case 7: - case 8: - case 9: - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - case 16: - case 17: - case 18: - case 19: - case 20: - case 21: - case 22: - case 23: - case 24: - case 25: - case 26: - break; - } - if (message.domain != null && message.hasOwnProperty("domain")) - if (!$util.isString(message.domain)) - return "domain: string expected"; - if (message.defaultValue != null && message.hasOwnProperty("defaultValue")) - if (!$util.isString(message.defaultValue)) - return "defaultValue: string expected"; - return null; - }; - - Field.fromObject = function fromObject(object) { + FeatureCollectionPBuffer.GeometryType = (function () { + var valuesById = {}, + values = Object.create(valuesById); + values[(valuesById[0] = 'esriGeometryTypePoint')] = 0; + values[(valuesById[1] = 'esriGeometryTypeMultipoint')] = 1; + values[(valuesById[2] = 'esriGeometryTypePolyline')] = 2; + values[(valuesById[3] = 'esriGeometryTypePolygon')] = 3; + values[(valuesById[4] = 'esriGeometryTypeMultipatch')] = 4; + values[(valuesById[127] = 'esriGeometryTypeNone')] = 127; + values[(valuesById[5] = 'esriGeometryTypeEnvelope')] = 5; + return values; + })(); + + FeatureCollectionPBuffer.FieldType = (function () { + var valuesById = {}, + values = Object.create(valuesById); + values[(valuesById[0] = 'esriFieldTypeSmallInteger')] = 0; + values[(valuesById[1] = 'esriFieldTypeInteger')] = 1; + values[(valuesById[2] = 'esriFieldTypeSingle')] = 2; + values[(valuesById[3] = 'esriFieldTypeDouble')] = 3; + values[(valuesById[4] = 'esriFieldTypeString')] = 4; + values[(valuesById[5] = 'esriFieldTypeDate')] = 5; + values[(valuesById[6] = 'esriFieldTypeOID')] = 6; + values[(valuesById[7] = 'esriFieldTypeGeometry')] = 7; + values[(valuesById[8] = 'esriFieldTypeBlob')] = 8; + values[(valuesById[9] = 'esriFieldTypeRaster')] = 9; + values[(valuesById[10] = 'esriFieldTypeGUID')] = 10; + values[(valuesById[11] = 'esriFieldTypeGlobalID')] = 11; + values[(valuesById[12] = 'esriFieldTypeXML')] = 12; + values[(valuesById[13] = 'esriFieldTypeBigInteger')] = 13; + values[(valuesById[14] = 'esriFieldTypeDateOnly')] = 14; + values[(valuesById[15] = 'esriFieldTypeTimeOnly')] = 15; + values[(valuesById[16] = 'esriFieldTypeTimestampOffset')] = 16; + return values; + })(); + + FeatureCollectionPBuffer.SQLType = (function () { + var valuesById = {}, + values = Object.create(valuesById); + values[(valuesById[0] = 'sqlTypeBigInt')] = 0; + values[(valuesById[1] = 'sqlTypeBinary')] = 1; + values[(valuesById[2] = 'sqlTypeBit')] = 2; + values[(valuesById[3] = 'sqlTypeChar')] = 3; + values[(valuesById[4] = 'sqlTypeDate')] = 4; + values[(valuesById[5] = 'sqlTypeDecimal')] = 5; + values[(valuesById[6] = 'sqlTypeDouble')] = 6; + values[(valuesById[7] = 'sqlTypeFloat')] = 7; + values[(valuesById[8] = 'sqlTypeGeometry')] = 8; + values[(valuesById[9] = 'sqlTypeGUID')] = 9; + values[(valuesById[10] = 'sqlTypeInteger')] = 10; + values[(valuesById[11] = 'sqlTypeLongNVarchar')] = 11; + values[(valuesById[12] = 'sqlTypeLongVarbinary')] = 12; + values[(valuesById[13] = 'sqlTypeLongVarchar')] = 13; + values[(valuesById[14] = 'sqlTypeNChar')] = 14; + values[(valuesById[15] = 'sqlTypeNVarchar')] = 15; + values[(valuesById[16] = 'sqlTypeOther')] = 16; + values[(valuesById[17] = 'sqlTypeReal')] = 17; + values[(valuesById[18] = 'sqlTypeSmallInt')] = 18; + values[(valuesById[19] = 'sqlTypeSqlXml')] = 19; + values[(valuesById[20] = 'sqlTypeTime')] = 20; + values[(valuesById[21] = 'sqlTypeTimestamp')] = 21; + values[(valuesById[22] = 'sqlTypeTimestamp2')] = 22; + values[(valuesById[23] = 'sqlTypeTinyInt')] = 23; + values[(valuesById[24] = 'sqlTypeVarbinary')] = 24; + values[(valuesById[25] = 'sqlTypeVarchar')] = 25; + values[(valuesById[26] = 'sqlTypeTimestampWithTimezone')] = 26; + return values; + })(); + + FeatureCollectionPBuffer.QuantizeOriginPostion = (function () { + var valuesById = {}, + values = Object.create(valuesById); + values[(valuesById[0] = 'upperLeft')] = 0; + values[(valuesById[1] = 'lowerLeft')] = 1; + return values; + })(); + + FeatureCollectionPBuffer.SpatialReference = (function () { + function SpatialReference(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + SpatialReference.prototype.wkid = 0; + SpatialReference.prototype.lastestWkid = 0; + SpatialReference.prototype.vcsWkid = 0; + SpatialReference.prototype.latestVcsWkid = 0; + SpatialReference.prototype.wkt = ''; + + SpatialReference.create = function create(properties) { + return new SpatialReference(properties); + }; + + SpatialReference.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.wkid != null && Object.hasOwnProperty.call(message, 'wkid')) + writer.uint32(8).uint32(message.wkid); + if ( + message.lastestWkid != null && + Object.hasOwnProperty.call(message, 'lastestWkid') + ) + writer.uint32(16).uint32(message.lastestWkid); + if ( + message.vcsWkid != null && + Object.hasOwnProperty.call(message, 'vcsWkid') + ) + writer.uint32(24).uint32(message.vcsWkid); + if ( + message.latestVcsWkid != null && + Object.hasOwnProperty.call(message, 'latestVcsWkid') + ) + writer.uint32(32).uint32(message.latestVcsWkid); + if (message.wkt != null && Object.hasOwnProperty.call(message, 'wkt')) + writer.uint32(42).string(message.wkt); + return writer; + }; + + SpatialReference.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + SpatialReference.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.wkid != null && message.hasOwnProperty('wkid')) + if (!$util.isInteger(message.wkid)) return 'wkid: integer expected'; + if ( + message.lastestWkid != null && + message.hasOwnProperty('lastestWkid') + ) + if (!$util.isInteger(message.lastestWkid)) + return 'lastestWkid: integer expected'; + if (message.vcsWkid != null && message.hasOwnProperty('vcsWkid')) + if (!$util.isInteger(message.vcsWkid)) + return 'vcsWkid: integer expected'; + if ( + message.latestVcsWkid != null && + message.hasOwnProperty('latestVcsWkid') + ) + if (!$util.isInteger(message.latestVcsWkid)) + return 'latestVcsWkid: integer expected'; + if (message.wkt != null && message.hasOwnProperty('wkt')) + if (!$util.isString(message.wkt)) return 'wkt: string expected'; + return null; + }; + + SpatialReference.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference(); + if (object.wkid != null) message.wkid = object.wkid >>> 0; + if (object.lastestWkid != null) + message.lastestWkid = object.lastestWkid >>> 0; + if (object.vcsWkid != null) message.vcsWkid = object.vcsWkid >>> 0; + if (object.latestVcsWkid != null) + message.latestVcsWkid = object.latestVcsWkid >>> 0; + if (object.wkt != null) message.wkt = String(object.wkt); + return message; + }; + + SpatialReference.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.wkid = 0; + object.lastestWkid = 0; + object.vcsWkid = 0; + object.latestVcsWkid = 0; + object.wkt = ''; + } + if (message.wkid != null && message.hasOwnProperty('wkid')) + object.wkid = message.wkid; + if ( + message.lastestWkid != null && + message.hasOwnProperty('lastestWkid') + ) + object.lastestWkid = message.lastestWkid; + if (message.vcsWkid != null && message.hasOwnProperty('vcsWkid')) + object.vcsWkid = message.vcsWkid; + if ( + message.latestVcsWkid != null && + message.hasOwnProperty('latestVcsWkid') + ) + object.latestVcsWkid = message.latestVcsWkid; + if (message.wkt != null && message.hasOwnProperty('wkt')) + object.wkt = message.wkt; + return object; + }; + + SpatialReference.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + SpatialReference.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + + '/esriPBuffer.FeatureCollectionPBuffer.SpatialReference' + ); + }; + + return SpatialReference; + })(); + + FeatureCollectionPBuffer.Field = (function () { + function Field(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Field.prototype.name = ''; + Field.prototype.fieldType = 0; + Field.prototype.alias = ''; + Field.prototype.sqlType = 0; + Field.prototype.domain = ''; + Field.prototype.defaultValue = ''; + + Field.create = function create(properties) { + return new Field(properties); + }; + + Field.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, 'name')) + writer.uint32(10).string(message.name); + if ( + message.fieldType != null && + Object.hasOwnProperty.call(message, 'fieldType') + ) + writer.uint32(16).int32(message.fieldType); + if ( + message.alias != null && + Object.hasOwnProperty.call(message, 'alias') + ) + writer.uint32(26).string(message.alias); + if ( + message.sqlType != null && + Object.hasOwnProperty.call(message, 'sqlType') + ) + writer.uint32(32).int32(message.sqlType); + if ( + message.domain != null && + Object.hasOwnProperty.call(message, 'domain') + ) + writer.uint32(42).string(message.domain); + if ( + message.defaultValue != null && + Object.hasOwnProperty.call(message, 'defaultValue') + ) + writer.uint32(50).string(message.defaultValue); + return writer; + }; + + Field.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Field.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.name != null && message.hasOwnProperty('name')) + if (!$util.isString(message.name)) return 'name: string expected'; + if (message.fieldType != null && message.hasOwnProperty('fieldType')) + switch (message.fieldType) { + default: + return 'fieldType: enum value expected'; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + break; + } + if (message.alias != null && message.hasOwnProperty('alias')) + if (!$util.isString(message.alias)) return 'alias: string expected'; + if (message.sqlType != null && message.hasOwnProperty('sqlType')) + switch (message.sqlType) { + default: + return 'sqlType: enum value expected'; + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + break; + } + if (message.domain != null && message.hasOwnProperty('domain')) + if (!$util.isString(message.domain)) return 'domain: string expected'; + if ( + message.defaultValue != null && + message.hasOwnProperty('defaultValue') + ) + if (!$util.isString(message.defaultValue)) + return 'defaultValue: string expected'; + return null; + }; + + Field.fromObject = function fromObject(object) { if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Field) - return object; + return object; var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Field(); - if (object.name != null) - message.name = String(object.name); + if (object.name != null) message.name = String(object.name); switch (object.fieldType) { - default: - if (typeof object.fieldType === "number") { - message.fieldType = object.fieldType; - break; + default: + if (typeof object.fieldType === 'number') { + message.fieldType = object.fieldType; + break; } break; - case "esriFieldTypeSmallInteger": - case 0: + case 'esriFieldTypeSmallInteger': + case 0: message.fieldType = 0; break; - case "esriFieldTypeInteger": - case 1: + case 'esriFieldTypeInteger': + case 1: message.fieldType = 1; break; - case "esriFieldTypeSingle": - case 2: + case 'esriFieldTypeSingle': + case 2: message.fieldType = 2; break; - case "esriFieldTypeDouble": - case 3: + case 'esriFieldTypeDouble': + case 3: message.fieldType = 3; break; - case "esriFieldTypeString": - case 4: + case 'esriFieldTypeString': + case 4: message.fieldType = 4; break; - case "esriFieldTypeDate": - case 5: + case 'esriFieldTypeDate': + case 5: message.fieldType = 5; break; - case "esriFieldTypeOID": - case 6: + case 'esriFieldTypeOID': + case 6: message.fieldType = 6; break; - case "esriFieldTypeGeometry": - case 7: + case 'esriFieldTypeGeometry': + case 7: message.fieldType = 7; break; - case "esriFieldTypeBlob": - case 8: + case 'esriFieldTypeBlob': + case 8: message.fieldType = 8; break; - case "esriFieldTypeRaster": - case 9: + case 'esriFieldTypeRaster': + case 9: message.fieldType = 9; break; - case "esriFieldTypeGUID": - case 10: + case 'esriFieldTypeGUID': + case 10: message.fieldType = 10; break; - case "esriFieldTypeGlobalID": - case 11: + case 'esriFieldTypeGlobalID': + case 11: message.fieldType = 11; break; - case "esriFieldTypeXML": - case 12: + case 'esriFieldTypeXML': + case 12: message.fieldType = 12; break; - case "esriFieldTypeBigInteger": - case 13: + case 'esriFieldTypeBigInteger': + case 13: message.fieldType = 13; break; - case "esriFieldTypeDateOnly": - case 14: + case 'esriFieldTypeDateOnly': + case 14: message.fieldType = 14; break; - case "esriFieldTypeTimeOnly": - case 15: + case 'esriFieldTypeTimeOnly': + case 15: message.fieldType = 15; break; - case "esriFieldTypeTimestampOffset": - case 16: + case 'esriFieldTypeTimestampOffset': + case 16: message.fieldType = 16; break; } - if (object.alias != null) - message.alias = String(object.alias); + if (object.alias != null) message.alias = String(object.alias); switch (object.sqlType) { - default: - if (typeof object.sqlType === "number") { - message.sqlType = object.sqlType; - break; + default: + if (typeof object.sqlType === 'number') { + message.sqlType = object.sqlType; + break; } break; - case "sqlTypeBigInt": - case 0: + case 'sqlTypeBigInt': + case 0: message.sqlType = 0; break; - case "sqlTypeBinary": - case 1: + case 'sqlTypeBinary': + case 1: message.sqlType = 1; break; - case "sqlTypeBit": - case 2: + case 'sqlTypeBit': + case 2: message.sqlType = 2; break; - case "sqlTypeChar": - case 3: + case 'sqlTypeChar': + case 3: message.sqlType = 3; break; - case "sqlTypeDate": - case 4: + case 'sqlTypeDate': + case 4: message.sqlType = 4; break; - case "sqlTypeDecimal": - case 5: + case 'sqlTypeDecimal': + case 5: message.sqlType = 5; break; - case "sqlTypeDouble": - case 6: + case 'sqlTypeDouble': + case 6: message.sqlType = 6; break; - case "sqlTypeFloat": - case 7: + case 'sqlTypeFloat': + case 7: message.sqlType = 7; break; - case "sqlTypeGeometry": - case 8: + case 'sqlTypeGeometry': + case 8: message.sqlType = 8; break; - case "sqlTypeGUID": - case 9: + case 'sqlTypeGUID': + case 9: message.sqlType = 9; break; - case "sqlTypeInteger": - case 10: + case 'sqlTypeInteger': + case 10: message.sqlType = 10; break; - case "sqlTypeLongNVarchar": - case 11: + case 'sqlTypeLongNVarchar': + case 11: message.sqlType = 11; break; - case "sqlTypeLongVarbinary": - case 12: + case 'sqlTypeLongVarbinary': + case 12: message.sqlType = 12; break; - case "sqlTypeLongVarchar": - case 13: + case 'sqlTypeLongVarchar': + case 13: message.sqlType = 13; break; - case "sqlTypeNChar": - case 14: + case 'sqlTypeNChar': + case 14: message.sqlType = 14; break; - case "sqlTypeNVarchar": - case 15: + case 'sqlTypeNVarchar': + case 15: message.sqlType = 15; break; - case "sqlTypeOther": - case 16: + case 'sqlTypeOther': + case 16: message.sqlType = 16; break; - case "sqlTypeReal": - case 17: + case 'sqlTypeReal': + case 17: message.sqlType = 17; break; - case "sqlTypeSmallInt": - case 18: + case 'sqlTypeSmallInt': + case 18: message.sqlType = 18; break; - case "sqlTypeSqlXml": - case 19: + case 'sqlTypeSqlXml': + case 19: message.sqlType = 19; break; - case "sqlTypeTime": - case 20: + case 'sqlTypeTime': + case 20: message.sqlType = 20; break; - case "sqlTypeTimestamp": - case 21: + case 'sqlTypeTimestamp': + case 21: message.sqlType = 21; break; - case "sqlTypeTimestamp2": - case 22: + case 'sqlTypeTimestamp2': + case 22: message.sqlType = 22; break; - case "sqlTypeTinyInt": - case 23: + case 'sqlTypeTinyInt': + case 23: message.sqlType = 23; break; - case "sqlTypeVarbinary": - case 24: + case 'sqlTypeVarbinary': + case 24: message.sqlType = 24; break; - case "sqlTypeVarchar": - case 25: + case 'sqlTypeVarchar': + case 25: message.sqlType = 25; break; - case "sqlTypeTimestampWithTimezone": - case 26: + case 'sqlTypeTimestampWithTimezone': + case 26: message.sqlType = 26; break; } - if (object.domain != null) - message.domain = String(object.domain); + if (object.domain != null) message.domain = String(object.domain); if (object.defaultValue != null) - message.defaultValue = String(object.defaultValue); + message.defaultValue = String(object.defaultValue); return message; - }; + }; + + Field.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.name = ''; + object.fieldType = + options.enums === String ? 'esriFieldTypeSmallInteger' : 0; + object.alias = ''; + object.sqlType = options.enums === String ? 'sqlTypeBigInt' : 0; + object.domain = ''; + object.defaultValue = ''; + } + if (message.name != null && message.hasOwnProperty('name')) + object.name = message.name; + if (message.fieldType != null && message.hasOwnProperty('fieldType')) + object.fieldType = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer.FieldType[ + message.fieldType + ] === undefined + ? message.fieldType + : $root.esriPBuffer.FeatureCollectionPBuffer.FieldType[ + message.fieldType + ] + : message.fieldType; + if (message.alias != null && message.hasOwnProperty('alias')) + object.alias = message.alias; + if (message.sqlType != null && message.hasOwnProperty('sqlType')) + object.sqlType = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer.SQLType[ + message.sqlType + ] === undefined + ? message.sqlType + : $root.esriPBuffer.FeatureCollectionPBuffer.SQLType[ + message.sqlType + ] + : message.sqlType; + if (message.domain != null && message.hasOwnProperty('domain')) + object.domain = message.domain; + if ( + message.defaultValue != null && + message.hasOwnProperty('defaultValue') + ) + object.defaultValue = message.defaultValue; + return object; + }; + + Field.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Field.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Field'; + }; - Field.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.name = ""; - object.fieldType = options.enums === String ? "esriFieldTypeSmallInteger" : 0; - object.alias = ""; - object.sqlType = options.enums === String ? "sqlTypeBigInt" : 0; - object.domain = ""; - object.defaultValue = ""; - } - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - if (message.fieldType != null && message.hasOwnProperty("fieldType")) - object.fieldType = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.FieldType[message.fieldType] === undefined ? message.fieldType : $root.esriPBuffer.FeatureCollectionPBuffer.FieldType[message.fieldType] : message.fieldType; - if (message.alias != null && message.hasOwnProperty("alias")) - object.alias = message.alias; - if (message.sqlType != null && message.hasOwnProperty("sqlType")) - object.sqlType = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.SQLType[message.sqlType] === undefined ? message.sqlType : $root.esriPBuffer.FeatureCollectionPBuffer.SQLType[message.sqlType] : message.sqlType; - if (message.domain != null && message.hasOwnProperty("domain")) - object.domain = message.domain; - if (message.defaultValue != null && message.hasOwnProperty("defaultValue")) - object.defaultValue = message.defaultValue; - return object; - }; - - Field.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Field.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Field"; - }; - - return Field; - })(); - - FeatureCollectionPBuffer.GeometryField = (function() { - - function GeometryField(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + return Field; + })(); - GeometryField.prototype.field = null; - GeometryField.prototype.geometryType = 0; - - GeometryField.create = function create(properties) { - return new GeometryField(properties); - }; - - GeometryField.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.field != null && Object.hasOwnProperty.call(message, "field")) - $root.esriPBuffer.FeatureCollectionPBuffer.Field.encode(message.field, writer.uint32(10).fork()).ldelim(); - if (message.geometryType != null && Object.hasOwnProperty.call(message, "geometryType")) - writer.uint32(16).int32(message.geometryType); - return writer; - }; - - GeometryField.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - GeometryField.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.field != null && message.hasOwnProperty("field")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Field.verify(message.field); - if (error) - return "field." + error; - } - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - switch (message.geometryType) { - default: - return "geometryType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 127: - case 5: - break; - } - return null; - }; - - GeometryField.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField(); - if (object.field != null) { - if (typeof object.field !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.GeometryField.field: object expected"); - message.field = $root.esriPBuffer.FeatureCollectionPBuffer.Field.fromObject(object.field); - } - switch (object.geometryType) { - default: - if (typeof object.geometryType === "number") { - message.geometryType = object.geometryType; - break; - } - break; - case "esriGeometryTypePoint": - case 0: - message.geometryType = 0; - break; - case "esriGeometryTypeMultipoint": - case 1: - message.geometryType = 1; - break; - case "esriGeometryTypePolyline": - case 2: - message.geometryType = 2; - break; - case "esriGeometryTypePolygon": - case 3: - message.geometryType = 3; - break; - case "esriGeometryTypeMultipatch": - case 4: - message.geometryType = 4; - break; - case "esriGeometryTypeNone": - case 127: - message.geometryType = 127; - break; - case "esriGeometryTypeEnvelope": - case 5: - message.geometryType = 5; - break; - } - return message; - }; - - GeometryField.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.field = null; - object.geometryType = options.enums === String ? "esriGeometryTypePoint" : 0; - } - if (message.field != null && message.hasOwnProperty("field")) - object.field = $root.esriPBuffer.FeatureCollectionPBuffer.Field.toObject(message.field, options); - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - object.geometryType = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] === undefined ? message.geometryType : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] : message.geometryType; - return object; - }; - - GeometryField.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - GeometryField.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.GeometryField"; - }; - - return GeometryField; - })(); - - FeatureCollectionPBuffer.Envelope = (function() { - - function Envelope(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; + FeatureCollectionPBuffer.GeometryField = (function () { + function GeometryField(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + GeometryField.prototype.field = null; + GeometryField.prototype.geometryType = 0; + + GeometryField.create = function create(properties) { + return new GeometryField(properties); + }; + + GeometryField.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.field != null && + Object.hasOwnProperty.call(message, 'field') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Field.encode( + message.field, + writer.uint32(10).fork(), + ).ldelim(); + if ( + message.geometryType != null && + Object.hasOwnProperty.call(message, 'geometryType') + ) + writer.uint32(16).int32(message.geometryType); + return writer; + }; + + GeometryField.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + GeometryField.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.field != null && message.hasOwnProperty('field')) { + var error = $root.esriPBuffer.FeatureCollectionPBuffer.Field.verify( + message.field, + ); + if (error) return 'field.' + error; + } + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + switch (message.geometryType) { + default: + return 'geometryType: enum value expected'; + case 0: + case 1: + case 2: + case 3: + case 4: + case 127: + case 5: + break; + } + return null; + }; + + GeometryField.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField(); + if (object.field != null) { + if (typeof object.field !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.GeometryField.field: object expected', + ); + message.field = + $root.esriPBuffer.FeatureCollectionPBuffer.Field.fromObject( + object.field, + ); + } + switch (object.geometryType) { + default: + if (typeof object.geometryType === 'number') { + message.geometryType = object.geometryType; + break; } + break; + case 'esriGeometryTypePoint': + case 0: + message.geometryType = 0; + break; + case 'esriGeometryTypeMultipoint': + case 1: + message.geometryType = 1; + break; + case 'esriGeometryTypePolyline': + case 2: + message.geometryType = 2; + break; + case 'esriGeometryTypePolygon': + case 3: + message.geometryType = 3; + break; + case 'esriGeometryTypeMultipatch': + case 4: + message.geometryType = 4; + break; + case 'esriGeometryTypeNone': + case 127: + message.geometryType = 127; + break; + case 'esriGeometryTypeEnvelope': + case 5: + message.geometryType = 5; + break; + } + return message; + }; + + GeometryField.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.field = null; + object.geometryType = + options.enums === String ? 'esriGeometryTypePoint' : 0; + } + if (message.field != null && message.hasOwnProperty('field')) + object.field = + $root.esriPBuffer.FeatureCollectionPBuffer.Field.toObject( + message.field, + options, + ); + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + object.geometryType = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] === undefined + ? message.geometryType + : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] + : message.geometryType; + return object; + }; + + GeometryField.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + GeometryField.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.GeometryField' + ); + }; - Envelope.prototype.XMin = 0; - Envelope.prototype.YMin = 0; - Envelope.prototype.XMax = 0; - Envelope.prototype.YMax = 0; - Envelope.prototype.SpatialReference = null; - - Envelope.create = function create(properties) { - return new Envelope(properties); - }; - - Envelope.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.XMin != null && Object.hasOwnProperty.call(message, "XMin")) - writer.uint32(9).double(message.XMin); - if (message.YMin != null && Object.hasOwnProperty.call(message, "YMin")) - writer.uint32(17).double(message.YMin); - if (message.XMax != null && Object.hasOwnProperty.call(message, "XMax")) - writer.uint32(25).double(message.XMax); - if (message.YMax != null && Object.hasOwnProperty.call(message, "YMax")) - writer.uint32(33).double(message.YMax); - if (message.SpatialReference != null && Object.hasOwnProperty.call(message, "SpatialReference")) - $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.encode(message.SpatialReference, writer.uint32(42).fork()).ldelim(); - return writer; - }; - - Envelope.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Envelope.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.XMin != null && message.hasOwnProperty("XMin")) - if (typeof message.XMin !== "number") - return "XMin: number expected"; - if (message.YMin != null && message.hasOwnProperty("YMin")) - if (typeof message.YMin !== "number") - return "YMin: number expected"; - if (message.XMax != null && message.hasOwnProperty("XMax")) - if (typeof message.XMax !== "number") - return "XMax: number expected"; - if (message.YMax != null && message.hasOwnProperty("YMax")) - if (typeof message.YMax !== "number") - return "YMax: number expected"; - if (message.SpatialReference != null && message.hasOwnProperty("SpatialReference")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.verify(message.SpatialReference); - if (error) - return "SpatialReference." + error; - } - return null; - }; - - Envelope.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Envelope) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Envelope(); - if (object.XMin != null) - message.XMin = Number(object.XMin); - if (object.YMin != null) - message.YMin = Number(object.YMin); - if (object.XMax != null) - message.XMax = Number(object.XMax); - if (object.YMax != null) - message.YMax = Number(object.YMax); - if (object.SpatialReference != null) { - if (typeof object.SpatialReference !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Envelope.SpatialReference: object expected"); - message.SpatialReference = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.fromObject(object.SpatialReference); - } - return message; - }; - - Envelope.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.XMin = 0; - object.YMin = 0; - object.XMax = 0; - object.YMax = 0; - object.SpatialReference = null; - } - if (message.XMin != null && message.hasOwnProperty("XMin")) - object.XMin = options.json && !isFinite(message.XMin) ? String(message.XMin) : message.XMin; - if (message.YMin != null && message.hasOwnProperty("YMin")) - object.YMin = options.json && !isFinite(message.YMin) ? String(message.YMin) : message.YMin; - if (message.XMax != null && message.hasOwnProperty("XMax")) - object.XMax = options.json && !isFinite(message.XMax) ? String(message.XMax) : message.XMax; - if (message.YMax != null && message.hasOwnProperty("YMax")) - object.YMax = options.json && !isFinite(message.YMax) ? String(message.YMax) : message.YMax; - if (message.SpatialReference != null && message.hasOwnProperty("SpatialReference")) - object.SpatialReference = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.toObject(message.SpatialReference, options); - return object; - }; - - Envelope.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Envelope.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Envelope"; - }; - - return Envelope; - })(); - - FeatureCollectionPBuffer.Value = (function() { - - function Value(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + return GeometryField; + })(); - Value.prototype.stringValue = null; - Value.prototype.floatValue = null; - Value.prototype.doubleValue = null; - Value.prototype.sintValue = null; - Value.prototype.uintValue = null; - Value.prototype.int64Value = null; - Value.prototype.uint64Value = null; - Value.prototype.sint64Value = null; - Value.prototype.boolValue = null; - - var $oneOfFields; - - Object.defineProperty(Value.prototype, "valueType", { - get: $util.oneOfGetter($oneOfFields = ["stringValue", "floatValue", "doubleValue", "sintValue", "uintValue", "int64Value", "uint64Value", "sint64Value", "boolValue"]), - set: $util.oneOfSetter($oneOfFields) - }); - - Value.create = function create(properties) { - return new Value(properties); - }; - - Value.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.stringValue != null && Object.hasOwnProperty.call(message, "stringValue")) - writer.uint32(10).string(message.stringValue); - if (message.floatValue != null && Object.hasOwnProperty.call(message, "floatValue")) - writer.uint32(21).float(message.floatValue); - if (message.doubleValue != null && Object.hasOwnProperty.call(message, "doubleValue")) - writer.uint32(25).double(message.doubleValue); - if (message.sintValue != null && Object.hasOwnProperty.call(message, "sintValue")) - writer.uint32(32).sint32(message.sintValue); - if (message.uintValue != null && Object.hasOwnProperty.call(message, "uintValue")) - writer.uint32(40).uint32(message.uintValue); - if (message.int64Value != null && Object.hasOwnProperty.call(message, "int64Value")) - writer.uint32(48).int64(message.int64Value); - if (message.uint64Value != null && Object.hasOwnProperty.call(message, "uint64Value")) - writer.uint32(56).uint64(message.uint64Value); - if (message.sint64Value != null && Object.hasOwnProperty.call(message, "sint64Value")) - writer.uint32(64).sint64(message.sint64Value); - if (message.boolValue != null && Object.hasOwnProperty.call(message, "boolValue")) - writer.uint32(72).bool(message.boolValue); - return writer; - }; - - Value.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Value.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.stringValue != null && message.hasOwnProperty("stringValue")) { - properties.valueType = 1; - if (!$util.isString(message.stringValue)) - return "stringValue: string expected"; - } - if (message.floatValue != null && message.hasOwnProperty("floatValue")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (typeof message.floatValue !== "number") - return "floatValue: number expected"; - } - if (message.doubleValue != null && message.hasOwnProperty("doubleValue")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (typeof message.doubleValue !== "number") - return "doubleValue: number expected"; - } - if (message.sintValue != null && message.hasOwnProperty("sintValue")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (!$util.isInteger(message.sintValue)) - return "sintValue: integer expected"; - } - if (message.uintValue != null && message.hasOwnProperty("uintValue")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (!$util.isInteger(message.uintValue)) - return "uintValue: integer expected"; - } - if (message.int64Value != null && message.hasOwnProperty("int64Value")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (!$util.isInteger(message.int64Value) && !(message.int64Value && $util.isInteger(message.int64Value.low) && $util.isInteger(message.int64Value.high))) - return "int64Value: integer|Long expected"; - } - if (message.uint64Value != null && message.hasOwnProperty("uint64Value")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (!$util.isInteger(message.uint64Value) && !(message.uint64Value && $util.isInteger(message.uint64Value.low) && $util.isInteger(message.uint64Value.high))) - return "uint64Value: integer|Long expected"; - } - if (message.sint64Value != null && message.hasOwnProperty("sint64Value")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (!$util.isInteger(message.sint64Value) && !(message.sint64Value && $util.isInteger(message.sint64Value.low) && $util.isInteger(message.sint64Value.high))) - return "sint64Value: integer|Long expected"; - } - if (message.boolValue != null && message.hasOwnProperty("boolValue")) { - if (properties.valueType === 1) - return "valueType: multiple values"; - properties.valueType = 1; - if (typeof message.boolValue !== "boolean") - return "boolValue: boolean expected"; - } - return null; - }; - - Value.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Value) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Value(); - if (object.stringValue != null) - message.stringValue = String(object.stringValue); - if (object.floatValue != null) - message.floatValue = Number(object.floatValue); - if (object.doubleValue != null) - message.doubleValue = Number(object.doubleValue); - if (object.sintValue != null) - message.sintValue = object.sintValue | 0; - if (object.uintValue != null) - message.uintValue = object.uintValue >>> 0; - if (object.int64Value != null) - if ($util.Long) - (message.int64Value = $util.Long.fromValue(object.int64Value)).unsigned = false; - else if (typeof object.int64Value === "string") - message.int64Value = parseInt(object.int64Value, 10); - else if (typeof object.int64Value === "number") - message.int64Value = object.int64Value; - else if (typeof object.int64Value === "object") - message.int64Value = new $util.LongBits(object.int64Value.low >>> 0, object.int64Value.high >>> 0).toNumber(); - if (object.uint64Value != null) - if ($util.Long) - (message.uint64Value = $util.Long.fromValue(object.uint64Value)).unsigned = true; - else if (typeof object.uint64Value === "string") - message.uint64Value = parseInt(object.uint64Value, 10); - else if (typeof object.uint64Value === "number") - message.uint64Value = object.uint64Value; - else if (typeof object.uint64Value === "object") - message.uint64Value = new $util.LongBits(object.uint64Value.low >>> 0, object.uint64Value.high >>> 0).toNumber(true); - if (object.sint64Value != null) - if ($util.Long) - (message.sint64Value = $util.Long.fromValue(object.sint64Value)).unsigned = false; - else if (typeof object.sint64Value === "string") - message.sint64Value = parseInt(object.sint64Value, 10); - else if (typeof object.sint64Value === "number") - message.sint64Value = object.sint64Value; - else if (typeof object.sint64Value === "object") - message.sint64Value = new $util.LongBits(object.sint64Value.low >>> 0, object.sint64Value.high >>> 0).toNumber(); - if (object.boolValue != null) - message.boolValue = Boolean(object.boolValue); - return message; - }; - - Value.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (message.stringValue != null && message.hasOwnProperty("stringValue")) { - object.stringValue = message.stringValue; - if (options.oneofs) - object.valueType = "stringValue"; - } - if (message.floatValue != null && message.hasOwnProperty("floatValue")) { - object.floatValue = options.json && !isFinite(message.floatValue) ? String(message.floatValue) : message.floatValue; - if (options.oneofs) - object.valueType = "floatValue"; - } - if (message.doubleValue != null && message.hasOwnProperty("doubleValue")) { - object.doubleValue = options.json && !isFinite(message.doubleValue) ? String(message.doubleValue) : message.doubleValue; - if (options.oneofs) - object.valueType = "doubleValue"; - } - if (message.sintValue != null && message.hasOwnProperty("sintValue")) { - object.sintValue = message.sintValue; - if (options.oneofs) - object.valueType = "sintValue"; - } - if (message.uintValue != null && message.hasOwnProperty("uintValue")) { - object.uintValue = message.uintValue; - if (options.oneofs) - object.valueType = "uintValue"; - } - if (message.int64Value != null && message.hasOwnProperty("int64Value")) { - if (typeof message.int64Value === "number") - object.int64Value = options.longs === String ? String(message.int64Value) : message.int64Value; - else - object.int64Value = options.longs === String ? $util.Long.prototype.toString.call(message.int64Value) : options.longs === Number ? new $util.LongBits(message.int64Value.low >>> 0, message.int64Value.high >>> 0).toNumber() : message.int64Value; - if (options.oneofs) - object.valueType = "int64Value"; - } - if (message.uint64Value != null && message.hasOwnProperty("uint64Value")) { - if (typeof message.uint64Value === "number") - object.uint64Value = options.longs === String ? String(message.uint64Value) : message.uint64Value; - else - object.uint64Value = options.longs === String ? $util.Long.prototype.toString.call(message.uint64Value) : options.longs === Number ? new $util.LongBits(message.uint64Value.low >>> 0, message.uint64Value.high >>> 0).toNumber(true) : message.uint64Value; - if (options.oneofs) - object.valueType = "uint64Value"; - } - if (message.sint64Value != null && message.hasOwnProperty("sint64Value")) { - if (typeof message.sint64Value === "number") - object.sint64Value = options.longs === String ? String(message.sint64Value) : message.sint64Value; - else - object.sint64Value = options.longs === String ? $util.Long.prototype.toString.call(message.sint64Value) : options.longs === Number ? new $util.LongBits(message.sint64Value.low >>> 0, message.sint64Value.high >>> 0).toNumber() : message.sint64Value; - if (options.oneofs) - object.valueType = "sint64Value"; - } - if (message.boolValue != null && message.hasOwnProperty("boolValue")) { - object.boolValue = message.boolValue; - if (options.oneofs) - object.valueType = "boolValue"; - } - return object; - }; - - Value.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Value.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Value"; - }; - - return Value; - })(); - - FeatureCollectionPBuffer.Geometry = (function() { - - function Geometry(properties) { - this.lengths = []; - this.coords = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.Envelope = (function () { + function Envelope(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Envelope.prototype.XMin = 0; + Envelope.prototype.YMin = 0; + Envelope.prototype.XMax = 0; + Envelope.prototype.YMax = 0; + Envelope.prototype.SpatialReference = null; + + Envelope.create = function create(properties) { + return new Envelope(properties); + }; + + Envelope.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.XMin != null && Object.hasOwnProperty.call(message, 'XMin')) + writer.uint32(9).double(message.XMin); + if (message.YMin != null && Object.hasOwnProperty.call(message, 'YMin')) + writer.uint32(17).double(message.YMin); + if (message.XMax != null && Object.hasOwnProperty.call(message, 'XMax')) + writer.uint32(25).double(message.XMax); + if (message.YMax != null && Object.hasOwnProperty.call(message, 'YMax')) + writer.uint32(33).double(message.YMax); + if ( + message.SpatialReference != null && + Object.hasOwnProperty.call(message, 'SpatialReference') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.encode( + message.SpatialReference, + writer.uint32(42).fork(), + ).ldelim(); + return writer; + }; + + Envelope.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Envelope.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.XMin != null && message.hasOwnProperty('XMin')) + if (typeof message.XMin !== 'number') return 'XMin: number expected'; + if (message.YMin != null && message.hasOwnProperty('YMin')) + if (typeof message.YMin !== 'number') return 'YMin: number expected'; + if (message.XMax != null && message.hasOwnProperty('XMax')) + if (typeof message.XMax !== 'number') return 'XMax: number expected'; + if (message.YMax != null && message.hasOwnProperty('YMax')) + if (typeof message.YMax !== 'number') return 'YMax: number expected'; + if ( + message.SpatialReference != null && + message.hasOwnProperty('SpatialReference') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.verify( + message.SpatialReference, + ); + if (error) return 'SpatialReference.' + error; + } + return null; + }; + + Envelope.fromObject = function fromObject(object) { + if ( + object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Envelope + ) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Envelope(); + if (object.XMin != null) message.XMin = Number(object.XMin); + if (object.YMin != null) message.YMin = Number(object.YMin); + if (object.XMax != null) message.XMax = Number(object.XMax); + if (object.YMax != null) message.YMax = Number(object.YMax); + if (object.SpatialReference != null) { + if (typeof object.SpatialReference !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Envelope.SpatialReference: object expected', + ); + message.SpatialReference = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.fromObject( + object.SpatialReference, + ); + } + return message; + }; + + Envelope.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.XMin = 0; + object.YMin = 0; + object.XMax = 0; + object.YMax = 0; + object.SpatialReference = null; + } + if (message.XMin != null && message.hasOwnProperty('XMin')) + object.XMin = + options.json && !isFinite(message.XMin) + ? String(message.XMin) + : message.XMin; + if (message.YMin != null && message.hasOwnProperty('YMin')) + object.YMin = + options.json && !isFinite(message.YMin) + ? String(message.YMin) + : message.YMin; + if (message.XMax != null && message.hasOwnProperty('XMax')) + object.XMax = + options.json && !isFinite(message.XMax) + ? String(message.XMax) + : message.XMax; + if (message.YMax != null && message.hasOwnProperty('YMax')) + object.YMax = + options.json && !isFinite(message.YMax) + ? String(message.YMax) + : message.YMax; + if ( + message.SpatialReference != null && + message.hasOwnProperty('SpatialReference') + ) + object.SpatialReference = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.toObject( + message.SpatialReference, + options, + ); + return object; + }; + + Envelope.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Envelope.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Envelope'; + }; - Geometry.prototype.geometryType = 0; - Geometry.prototype.lengths = $util.emptyArray; - Geometry.prototype.coords = $util.emptyArray; - - Geometry.create = function create(properties) { - return new Geometry(properties); - }; - - Geometry.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.geometryType != null && Object.hasOwnProperty.call(message, "geometryType")) - writer.uint32(8).int32(message.geometryType); - if (message.lengths != null && message.lengths.length) { - writer.uint32(18).fork(); - for (var i = 0; i < message.lengths.length; ++i) - writer.uint32(message.lengths[i]); - writer.ldelim(); - } - if (message.coords != null && message.coords.length) { - writer.uint32(26).fork(); - for (var i = 0; i < message.coords.length; ++i) - writer.sint64(message.coords[i]); - writer.ldelim(); - } - return writer; - }; - - Geometry.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Geometry.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - switch (message.geometryType) { - default: - return "geometryType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 127: - case 5: - break; - } - if (message.lengths != null && message.hasOwnProperty("lengths")) { - if (!Array.isArray(message.lengths)) - return "lengths: array expected"; - for (var i = 0; i < message.lengths.length; ++i) - if (!$util.isInteger(message.lengths[i])) - return "lengths: integer[] expected"; - } - if (message.coords != null && message.hasOwnProperty("coords")) { - if (!Array.isArray(message.coords)) - return "coords: array expected"; - for (var i = 0; i < message.coords.length; ++i) - if (!$util.isInteger(message.coords[i]) && !(message.coords[i] && $util.isInteger(message.coords[i].low) && $util.isInteger(message.coords[i].high))) - return "coords: integer|Long[] expected"; - } - return null; - }; - - Geometry.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Geometry) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Geometry(); - switch (object.geometryType) { - default: - if (typeof object.geometryType === "number") { - message.geometryType = object.geometryType; - break; - } - break; - case "esriGeometryTypePoint": - case 0: - message.geometryType = 0; - break; - case "esriGeometryTypeMultipoint": - case 1: - message.geometryType = 1; - break; - case "esriGeometryTypePolyline": - case 2: - message.geometryType = 2; - break; - case "esriGeometryTypePolygon": - case 3: - message.geometryType = 3; - break; - case "esriGeometryTypeMultipatch": - case 4: - message.geometryType = 4; - break; - case "esriGeometryTypeNone": - case 127: - message.geometryType = 127; - break; - case "esriGeometryTypeEnvelope": - case 5: - message.geometryType = 5; - break; - } - if (object.lengths) { - if (!Array.isArray(object.lengths)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Geometry.lengths: array expected"); - message.lengths = []; - for (var i = 0; i < object.lengths.length; ++i) - message.lengths[i] = object.lengths[i] >>> 0; - } - if (object.coords) { - if (!Array.isArray(object.coords)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Geometry.coords: array expected"); - message.coords = []; - for (var i = 0; i < object.coords.length; ++i) - if ($util.Long) - (message.coords[i] = $util.Long.fromValue(object.coords[i])).unsigned = false; - else if (typeof object.coords[i] === "string") - message.coords[i] = parseInt(object.coords[i], 10); - else if (typeof object.coords[i] === "number") - message.coords[i] = object.coords[i]; - else if (typeof object.coords[i] === "object") - message.coords[i] = new $util.LongBits(object.coords[i].low >>> 0, object.coords[i].high >>> 0).toNumber(); - } - return message; - }; - - Geometry.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.lengths = []; - object.coords = []; - } - if (options.defaults) - object.geometryType = options.enums === String ? "esriGeometryTypePoint" : 0; - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - object.geometryType = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] === undefined ? message.geometryType : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] : message.geometryType; - if (message.lengths && message.lengths.length) { - object.lengths = []; - for (var j = 0; j < message.lengths.length; ++j) - object.lengths[j] = message.lengths[j]; - } - if (message.coords && message.coords.length) { - object.coords = []; - for (var j = 0; j < message.coords.length; ++j) - if (typeof message.coords[j] === "number") - object.coords[j] = options.longs === String ? String(message.coords[j]) : message.coords[j]; - else - object.coords[j] = options.longs === String ? $util.Long.prototype.toString.call(message.coords[j]) : options.longs === Number ? new $util.LongBits(message.coords[j].low >>> 0, message.coords[j].high >>> 0).toNumber() : message.coords[j]; - } - return object; - }; - - Geometry.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Geometry.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Geometry"; - }; - - return Geometry; - })(); - - FeatureCollectionPBuffer.esriShapeBuffer = (function() { - - function esriShapeBuffer(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + return Envelope; + })(); - esriShapeBuffer.prototype.bytes = $util.newBuffer([]); - - esriShapeBuffer.create = function create(properties) { - return new esriShapeBuffer(properties); - }; - - esriShapeBuffer.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.bytes != null && Object.hasOwnProperty.call(message, "bytes")) - writer.uint32(10).bytes(message.bytes); - return writer; - }; - - esriShapeBuffer.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - esriShapeBuffer.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.bytes != null && message.hasOwnProperty("bytes")) - if (!(message.bytes && typeof message.bytes.length === "number" || $util.isString(message.bytes))) - return "bytes: buffer expected"; - return null; - }; - - esriShapeBuffer.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer(); - if (object.bytes != null) - if (typeof object.bytes === "string") - $util.base64.decode(object.bytes, message.bytes = $util.newBuffer($util.base64.length(object.bytes)), 0); - else if (object.bytes.length >= 0) - message.bytes = object.bytes; - return message; - }; - - esriShapeBuffer.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if (options.bytes === String) - object.bytes = ""; - else { - object.bytes = []; - if (options.bytes !== Array) - object.bytes = $util.newBuffer(object.bytes); - } - if (message.bytes != null && message.hasOwnProperty("bytes")) - object.bytes = options.bytes === String ? $util.base64.encode(message.bytes, 0, message.bytes.length) : options.bytes === Array ? Array.prototype.slice.call(message.bytes) : message.bytes; - return object; - }; - - esriShapeBuffer.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - esriShapeBuffer.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer"; - }; - - return esriShapeBuffer; - })(); - - FeatureCollectionPBuffer.Feature = (function() { - - function Feature(properties) { - this.attributes = []; - this.aggregateGeometries = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.Value = (function () { + function Value(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Value.prototype.stringValue = null; + Value.prototype.floatValue = null; + Value.prototype.doubleValue = null; + Value.prototype.sintValue = null; + Value.prototype.uintValue = null; + Value.prototype.int64Value = null; + Value.prototype.uint64Value = null; + Value.prototype.sint64Value = null; + Value.prototype.boolValue = null; + + var $oneOfFields; + + Object.defineProperty(Value.prototype, 'valueType', { + get: $util.oneOfGetter( + ($oneOfFields = [ + 'stringValue', + 'floatValue', + 'doubleValue', + 'sintValue', + 'uintValue', + 'int64Value', + 'uint64Value', + 'sint64Value', + 'boolValue', + ]), + ), + set: $util.oneOfSetter($oneOfFields), + }); + + Value.create = function create(properties) { + return new Value(properties); + }; + + Value.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.stringValue != null && + Object.hasOwnProperty.call(message, 'stringValue') + ) + writer.uint32(10).string(message.stringValue); + if ( + message.floatValue != null && + Object.hasOwnProperty.call(message, 'floatValue') + ) + writer.uint32(21).float(message.floatValue); + if ( + message.doubleValue != null && + Object.hasOwnProperty.call(message, 'doubleValue') + ) + writer.uint32(25).double(message.doubleValue); + if ( + message.sintValue != null && + Object.hasOwnProperty.call(message, 'sintValue') + ) + writer.uint32(32).sint32(message.sintValue); + if ( + message.uintValue != null && + Object.hasOwnProperty.call(message, 'uintValue') + ) + writer.uint32(40).uint32(message.uintValue); + if ( + message.int64Value != null && + Object.hasOwnProperty.call(message, 'int64Value') + ) + writer.uint32(48).int64(message.int64Value); + if ( + message.uint64Value != null && + Object.hasOwnProperty.call(message, 'uint64Value') + ) + writer.uint32(56).uint64(message.uint64Value); + if ( + message.sint64Value != null && + Object.hasOwnProperty.call(message, 'sint64Value') + ) + writer.uint32(64).sint64(message.sint64Value); + if ( + message.boolValue != null && + Object.hasOwnProperty.call(message, 'boolValue') + ) + writer.uint32(72).bool(message.boolValue); + return writer; + }; + + Value.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Value.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + var properties = {}; + if ( + message.stringValue != null && + message.hasOwnProperty('stringValue') + ) { + properties.valueType = 1; + if (!$util.isString(message.stringValue)) + return 'stringValue: string expected'; + } + if ( + message.floatValue != null && + message.hasOwnProperty('floatValue') + ) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if (typeof message.floatValue !== 'number') + return 'floatValue: number expected'; + } + if ( + message.doubleValue != null && + message.hasOwnProperty('doubleValue') + ) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if (typeof message.doubleValue !== 'number') + return 'doubleValue: number expected'; + } + if (message.sintValue != null && message.hasOwnProperty('sintValue')) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if (!$util.isInteger(message.sintValue)) + return 'sintValue: integer expected'; + } + if (message.uintValue != null && message.hasOwnProperty('uintValue')) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if (!$util.isInteger(message.uintValue)) + return 'uintValue: integer expected'; + } + if ( + message.int64Value != null && + message.hasOwnProperty('int64Value') + ) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if ( + !$util.isInteger(message.int64Value) && + !( + message.int64Value && + $util.isInteger(message.int64Value.low) && + $util.isInteger(message.int64Value.high) + ) + ) + return 'int64Value: integer|Long expected'; + } + if ( + message.uint64Value != null && + message.hasOwnProperty('uint64Value') + ) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if ( + !$util.isInteger(message.uint64Value) && + !( + message.uint64Value && + $util.isInteger(message.uint64Value.low) && + $util.isInteger(message.uint64Value.high) + ) + ) + return 'uint64Value: integer|Long expected'; + } + if ( + message.sint64Value != null && + message.hasOwnProperty('sint64Value') + ) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if ( + !$util.isInteger(message.sint64Value) && + !( + message.sint64Value && + $util.isInteger(message.sint64Value.low) && + $util.isInteger(message.sint64Value.high) + ) + ) + return 'sint64Value: integer|Long expected'; + } + if (message.boolValue != null && message.hasOwnProperty('boolValue')) { + if (properties.valueType === 1) return 'valueType: multiple values'; + properties.valueType = 1; + if (typeof message.boolValue !== 'boolean') + return 'boolValue: boolean expected'; + } + return null; + }; + + Value.fromObject = function fromObject(object) { + if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Value) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Value(); + if (object.stringValue != null) + message.stringValue = String(object.stringValue); + if (object.floatValue != null) + message.floatValue = Number(object.floatValue); + if (object.doubleValue != null) + message.doubleValue = Number(object.doubleValue); + if (object.sintValue != null) message.sintValue = object.sintValue | 0; + if (object.uintValue != null) + message.uintValue = object.uintValue >>> 0; + if (object.int64Value != null) + if ($util.Long) + (message.int64Value = $util.Long.fromValue( + object.int64Value, + )).unsigned = false; + else if (typeof object.int64Value === 'string') + message.int64Value = parseInt(object.int64Value, 10); + else if (typeof object.int64Value === 'number') + message.int64Value = object.int64Value; + else if (typeof object.int64Value === 'object') + message.int64Value = new $util.LongBits( + object.int64Value.low >>> 0, + object.int64Value.high >>> 0, + ).toNumber(); + if (object.uint64Value != null) + if ($util.Long) + (message.uint64Value = $util.Long.fromValue( + object.uint64Value, + )).unsigned = true; + else if (typeof object.uint64Value === 'string') + message.uint64Value = parseInt(object.uint64Value, 10); + else if (typeof object.uint64Value === 'number') + message.uint64Value = object.uint64Value; + else if (typeof object.uint64Value === 'object') + message.uint64Value = new $util.LongBits( + object.uint64Value.low >>> 0, + object.uint64Value.high >>> 0, + ).toNumber(true); + if (object.sint64Value != null) + if ($util.Long) + (message.sint64Value = $util.Long.fromValue( + object.sint64Value, + )).unsigned = false; + else if (typeof object.sint64Value === 'string') + message.sint64Value = parseInt(object.sint64Value, 10); + else if (typeof object.sint64Value === 'number') + message.sint64Value = object.sint64Value; + else if (typeof object.sint64Value === 'object') + message.sint64Value = new $util.LongBits( + object.sint64Value.low >>> 0, + object.sint64Value.high >>> 0, + ).toNumber(); + if (object.boolValue != null) + message.boolValue = Boolean(object.boolValue); + return message; + }; + + Value.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if ( + message.stringValue != null && + message.hasOwnProperty('stringValue') + ) { + object.stringValue = message.stringValue; + if (options.oneofs) object.valueType = 'stringValue'; + } + if ( + message.floatValue != null && + message.hasOwnProperty('floatValue') + ) { + object.floatValue = + options.json && !isFinite(message.floatValue) + ? String(message.floatValue) + : message.floatValue; + if (options.oneofs) object.valueType = 'floatValue'; + } + if ( + message.doubleValue != null && + message.hasOwnProperty('doubleValue') + ) { + object.doubleValue = + options.json && !isFinite(message.doubleValue) + ? String(message.doubleValue) + : message.doubleValue; + if (options.oneofs) object.valueType = 'doubleValue'; + } + if (message.sintValue != null && message.hasOwnProperty('sintValue')) { + object.sintValue = message.sintValue; + if (options.oneofs) object.valueType = 'sintValue'; + } + if (message.uintValue != null && message.hasOwnProperty('uintValue')) { + object.uintValue = message.uintValue; + if (options.oneofs) object.valueType = 'uintValue'; + } + if ( + message.int64Value != null && + message.hasOwnProperty('int64Value') + ) { + if (typeof message.int64Value === 'number') + object.int64Value = + options.longs === String + ? String(message.int64Value) + : message.int64Value; + else + object.int64Value = + options.longs === String + ? $util.Long.prototype.toString.call(message.int64Value) + : options.longs === Number + ? new $util.LongBits( + message.int64Value.low >>> 0, + message.int64Value.high >>> 0, + ).toNumber() + : message.int64Value; + if (options.oneofs) object.valueType = 'int64Value'; + } + if ( + message.uint64Value != null && + message.hasOwnProperty('uint64Value') + ) { + if (typeof message.uint64Value === 'number') + object.uint64Value = + options.longs === String + ? String(message.uint64Value) + : message.uint64Value; + else + object.uint64Value = + options.longs === String + ? $util.Long.prototype.toString.call(message.uint64Value) + : options.longs === Number + ? new $util.LongBits( + message.uint64Value.low >>> 0, + message.uint64Value.high >>> 0, + ).toNumber(true) + : message.uint64Value; + if (options.oneofs) object.valueType = 'uint64Value'; + } + if ( + message.sint64Value != null && + message.hasOwnProperty('sint64Value') + ) { + if (typeof message.sint64Value === 'number') + object.sint64Value = + options.longs === String + ? String(message.sint64Value) + : message.sint64Value; + else + object.sint64Value = + options.longs === String + ? $util.Long.prototype.toString.call(message.sint64Value) + : options.longs === Number + ? new $util.LongBits( + message.sint64Value.low >>> 0, + message.sint64Value.high >>> 0, + ).toNumber() + : message.sint64Value; + if (options.oneofs) object.valueType = 'sint64Value'; + } + if (message.boolValue != null && message.hasOwnProperty('boolValue')) { + object.boolValue = message.boolValue; + if (options.oneofs) object.valueType = 'boolValue'; + } + return object; + }; - Feature.prototype.attributes = $util.emptyArray; - Feature.prototype.geometry = null; - Feature.prototype.shapeBuffer = null; - Feature.prototype.centroid = null; - Feature.prototype.aggregateGeometries = $util.emptyArray; - Feature.prototype.envelope = null; - - var $oneOfFields; - - Object.defineProperty(Feature.prototype, "compressedGeometry", { - get: $util.oneOfGetter($oneOfFields = ["geometry", "shapeBuffer"]), - set: $util.oneOfSetter($oneOfFields) - }); - - Feature.create = function create(properties) { - return new Feature(properties); - }; - - Feature.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.attributes != null && message.attributes.length) - for (var i = 0; i < message.attributes.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.Value.encode(message.attributes[i], writer.uint32(10).fork()).ldelim(); - if (message.geometry != null && Object.hasOwnProperty.call(message, "geometry")) - $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode(message.geometry, writer.uint32(18).fork()).ldelim(); - if (message.shapeBuffer != null && Object.hasOwnProperty.call(message, "shapeBuffer")) - $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.encode(message.shapeBuffer, writer.uint32(26).fork()).ldelim(); - if (message.centroid != null && Object.hasOwnProperty.call(message, "centroid")) - $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode(message.centroid, writer.uint32(34).fork()).ldelim(); - if (message.aggregateGeometries != null && message.aggregateGeometries.length) - for (var i = 0; i < message.aggregateGeometries.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode(message.aggregateGeometries[i], writer.uint32(42).fork()).ldelim(); - if (message.envelope != null && Object.hasOwnProperty.call(message, "envelope")) - $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.encode(message.envelope, writer.uint32(50).fork()).ldelim(); - return writer; - }; - - Feature.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Feature.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.attributes != null && message.hasOwnProperty("attributes")) { - if (!Array.isArray(message.attributes)) - return "attributes: array expected"; - for (var i = 0; i < message.attributes.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Value.verify(message.attributes[i]); - if (error) - return "attributes." + error; - } - } - if (message.geometry != null && message.hasOwnProperty("geometry")) { - properties.compressedGeometry = 1; - { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify(message.geometry); - if (error) - return "geometry." + error; - } - } - if (message.shapeBuffer != null && message.hasOwnProperty("shapeBuffer")) { - if (properties.compressedGeometry === 1) - return "compressedGeometry: multiple values"; - properties.compressedGeometry = 1; - { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.verify(message.shapeBuffer); - if (error) - return "shapeBuffer." + error; - } - } - if (message.centroid != null && message.hasOwnProperty("centroid")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify(message.centroid); - if (error) - return "centroid." + error; - } - if (message.aggregateGeometries != null && message.hasOwnProperty("aggregateGeometries")) { - if (!Array.isArray(message.aggregateGeometries)) - return "aggregateGeometries: array expected"; - for (var i = 0; i < message.aggregateGeometries.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify(message.aggregateGeometries[i]); - if (error) - return "aggregateGeometries." + error; - } - } - if (message.envelope != null && message.hasOwnProperty("envelope")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.verify(message.envelope); - if (error) - return "envelope." + error; - } - return null; - }; - - Feature.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Feature) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Feature(); - if (object.attributes) { - if (!Array.isArray(object.attributes)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.attributes: array expected"); - message.attributes = []; - for (var i = 0; i < object.attributes.length; ++i) { - if (typeof object.attributes[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.attributes: object expected"); - message.attributes[i] = $root.esriPBuffer.FeatureCollectionPBuffer.Value.fromObject(object.attributes[i]); - } - } - if (object.geometry != null) { - if (typeof object.geometry !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.geometry: object expected"); - message.geometry = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject(object.geometry); - } - if (object.shapeBuffer != null) { - if (typeof object.shapeBuffer !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.shapeBuffer: object expected"); - message.shapeBuffer = $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.fromObject(object.shapeBuffer); - } - if (object.centroid != null) { - if (typeof object.centroid !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.centroid: object expected"); - message.centroid = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject(object.centroid); - } - if (object.aggregateGeometries) { - if (!Array.isArray(object.aggregateGeometries)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.aggregateGeometries: array expected"); - message.aggregateGeometries = []; - for (var i = 0; i < object.aggregateGeometries.length; ++i) { - if (typeof object.aggregateGeometries[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.aggregateGeometries: object expected"); - message.aggregateGeometries[i] = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject(object.aggregateGeometries[i]); - } - } - if (object.envelope != null) { - if (typeof object.envelope !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Feature.envelope: object expected"); - message.envelope = $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.fromObject(object.envelope); - } - return message; - }; - - Feature.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.attributes = []; - object.aggregateGeometries = []; - } - if (options.defaults) { - object.centroid = null; - object.envelope = null; - } - if (message.attributes && message.attributes.length) { - object.attributes = []; - for (var j = 0; j < message.attributes.length; ++j) - object.attributes[j] = $root.esriPBuffer.FeatureCollectionPBuffer.Value.toObject(message.attributes[j], options); - } - if (message.geometry != null && message.hasOwnProperty("geometry")) { - object.geometry = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject(message.geometry, options); - if (options.oneofs) - object.compressedGeometry = "geometry"; - } - if (message.shapeBuffer != null && message.hasOwnProperty("shapeBuffer")) { - object.shapeBuffer = $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.toObject(message.shapeBuffer, options); - if (options.oneofs) - object.compressedGeometry = "shapeBuffer"; - } - if (message.centroid != null && message.hasOwnProperty("centroid")) - object.centroid = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject(message.centroid, options); - if (message.aggregateGeometries && message.aggregateGeometries.length) { - object.aggregateGeometries = []; - for (var j = 0; j < message.aggregateGeometries.length; ++j) - object.aggregateGeometries[j] = $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject(message.aggregateGeometries[j], options); - } - if (message.envelope != null && message.hasOwnProperty("envelope")) - object.envelope = $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.toObject(message.envelope, options); - return object; - }; - - Feature.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Feature.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Feature"; - }; - - return Feature; - })(); - - FeatureCollectionPBuffer.UniqueIdField = (function() { - - function UniqueIdField(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + Value.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - UniqueIdField.prototype.name = ""; - UniqueIdField.prototype.isSystemMaintained = false; - - UniqueIdField.create = function create(properties) { - return new UniqueIdField(properties); - }; - - UniqueIdField.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.name != null && Object.hasOwnProperty.call(message, "name")) - writer.uint32(10).string(message.name); - if (message.isSystemMaintained != null && Object.hasOwnProperty.call(message, "isSystemMaintained")) - writer.uint32(16).bool(message.isSystemMaintained); - return writer; - }; - - UniqueIdField.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - UniqueIdField.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.name != null && message.hasOwnProperty("name")) - if (!$util.isString(message.name)) - return "name: string expected"; - if (message.isSystemMaintained != null && message.hasOwnProperty("isSystemMaintained")) - if (typeof message.isSystemMaintained !== "boolean") - return "isSystemMaintained: boolean expected"; - return null; - }; - - UniqueIdField.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField(); - if (object.name != null) - message.name = String(object.name); - if (object.isSystemMaintained != null) - message.isSystemMaintained = Boolean(object.isSystemMaintained); - return message; - }; - - UniqueIdField.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.name = ""; - object.isSystemMaintained = false; - } - if (message.name != null && message.hasOwnProperty("name")) - object.name = message.name; - if (message.isSystemMaintained != null && message.hasOwnProperty("isSystemMaintained")) - object.isSystemMaintained = message.isSystemMaintained; - return object; - }; - - UniqueIdField.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - UniqueIdField.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.UniqueIdField"; - }; - - return UniqueIdField; - })(); - - FeatureCollectionPBuffer.GeometryProperties = (function() { - - function GeometryProperties(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + Value.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Value'; + }; - GeometryProperties.prototype.shapeAreaFieldName = ""; - GeometryProperties.prototype.shapeLengthFieldName = ""; - GeometryProperties.prototype.units = ""; - - GeometryProperties.create = function create(properties) { - return new GeometryProperties(properties); - }; - - GeometryProperties.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.shapeAreaFieldName != null && Object.hasOwnProperty.call(message, "shapeAreaFieldName")) - writer.uint32(10).string(message.shapeAreaFieldName); - if (message.shapeLengthFieldName != null && Object.hasOwnProperty.call(message, "shapeLengthFieldName")) - writer.uint32(18).string(message.shapeLengthFieldName); - if (message.units != null && Object.hasOwnProperty.call(message, "units")) - writer.uint32(26).string(message.units); - return writer; - }; - - GeometryProperties.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - GeometryProperties.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.shapeAreaFieldName != null && message.hasOwnProperty("shapeAreaFieldName")) - if (!$util.isString(message.shapeAreaFieldName)) - return "shapeAreaFieldName: string expected"; - if (message.shapeLengthFieldName != null && message.hasOwnProperty("shapeLengthFieldName")) - if (!$util.isString(message.shapeLengthFieldName)) - return "shapeLengthFieldName: string expected"; - if (message.units != null && message.hasOwnProperty("units")) - if (!$util.isString(message.units)) - return "units: string expected"; - return null; - }; - - GeometryProperties.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties(); - if (object.shapeAreaFieldName != null) - message.shapeAreaFieldName = String(object.shapeAreaFieldName); - if (object.shapeLengthFieldName != null) - message.shapeLengthFieldName = String(object.shapeLengthFieldName); - if (object.units != null) - message.units = String(object.units); - return message; - }; - - GeometryProperties.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.shapeAreaFieldName = ""; - object.shapeLengthFieldName = ""; - object.units = ""; - } - if (message.shapeAreaFieldName != null && message.hasOwnProperty("shapeAreaFieldName")) - object.shapeAreaFieldName = message.shapeAreaFieldName; - if (message.shapeLengthFieldName != null && message.hasOwnProperty("shapeLengthFieldName")) - object.shapeLengthFieldName = message.shapeLengthFieldName; - if (message.units != null && message.hasOwnProperty("units")) - object.units = message.units; - return object; - }; - - GeometryProperties.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - GeometryProperties.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.GeometryProperties"; - }; - - return GeometryProperties; - })(); - - FeatureCollectionPBuffer.ServerGens = (function() { - - function ServerGens(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + return Value; + })(); - ServerGens.prototype.minServerGen = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - ServerGens.prototype.serverGen = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - ServerGens.create = function create(properties) { - return new ServerGens(properties); - }; - - ServerGens.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.minServerGen != null && Object.hasOwnProperty.call(message, "minServerGen")) - writer.uint32(8).uint64(message.minServerGen); - if (message.serverGen != null && Object.hasOwnProperty.call(message, "serverGen")) - writer.uint32(16).uint64(message.serverGen); - return writer; - }; - - ServerGens.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - ServerGens.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.minServerGen != null && message.hasOwnProperty("minServerGen")) - if (!$util.isInteger(message.minServerGen) && !(message.minServerGen && $util.isInteger(message.minServerGen.low) && $util.isInteger(message.minServerGen.high))) - return "minServerGen: integer|Long expected"; - if (message.serverGen != null && message.hasOwnProperty("serverGen")) - if (!$util.isInteger(message.serverGen) && !(message.serverGen && $util.isInteger(message.serverGen.low) && $util.isInteger(message.serverGen.high))) - return "serverGen: integer|Long expected"; - return null; - }; - - ServerGens.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens(); - if (object.minServerGen != null) - if ($util.Long) - (message.minServerGen = $util.Long.fromValue(object.minServerGen)).unsigned = true; - else if (typeof object.minServerGen === "string") - message.minServerGen = parseInt(object.minServerGen, 10); - else if (typeof object.minServerGen === "number") - message.minServerGen = object.minServerGen; - else if (typeof object.minServerGen === "object") - message.minServerGen = new $util.LongBits(object.minServerGen.low >>> 0, object.minServerGen.high >>> 0).toNumber(true); - if (object.serverGen != null) - if ($util.Long) - (message.serverGen = $util.Long.fromValue(object.serverGen)).unsigned = true; - else if (typeof object.serverGen === "string") - message.serverGen = parseInt(object.serverGen, 10); - else if (typeof object.serverGen === "number") - message.serverGen = object.serverGen; - else if (typeof object.serverGen === "object") - message.serverGen = new $util.LongBits(object.serverGen.low >>> 0, object.serverGen.high >>> 0).toNumber(true); - return message; - }; - - ServerGens.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.minServerGen = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.minServerGen = options.longs === String ? "0" : 0; - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.serverGen = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.serverGen = options.longs === String ? "0" : 0; - } - if (message.minServerGen != null && message.hasOwnProperty("minServerGen")) - if (typeof message.minServerGen === "number") - object.minServerGen = options.longs === String ? String(message.minServerGen) : message.minServerGen; - else - object.minServerGen = options.longs === String ? $util.Long.prototype.toString.call(message.minServerGen) : options.longs === Number ? new $util.LongBits(message.minServerGen.low >>> 0, message.minServerGen.high >>> 0).toNumber(true) : message.minServerGen; - if (message.serverGen != null && message.hasOwnProperty("serverGen")) - if (typeof message.serverGen === "number") - object.serverGen = options.longs === String ? String(message.serverGen) : message.serverGen; - else - object.serverGen = options.longs === String ? $util.Long.prototype.toString.call(message.serverGen) : options.longs === Number ? new $util.LongBits(message.serverGen.low >>> 0, message.serverGen.high >>> 0).toNumber(true) : message.serverGen; - return object; - }; - - ServerGens.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - ServerGens.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.ServerGens"; - }; - - return ServerGens; - })(); - - FeatureCollectionPBuffer.Scale = (function() { - - function Scale(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; + FeatureCollectionPBuffer.Geometry = (function () { + function Geometry(properties) { + this.lengths = []; + this.coords = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Geometry.prototype.geometryType = 0; + Geometry.prototype.lengths = $util.emptyArray; + Geometry.prototype.coords = $util.emptyArray; + + Geometry.create = function create(properties) { + return new Geometry(properties); + }; + + Geometry.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.geometryType != null && + Object.hasOwnProperty.call(message, 'geometryType') + ) + writer.uint32(8).int32(message.geometryType); + if (message.lengths != null && message.lengths.length) { + writer.uint32(18).fork(); + for (var i = 0; i < message.lengths.length; ++i) + writer.uint32(message.lengths[i]); + writer.ldelim(); + } + if (message.coords != null && message.coords.length) { + writer.uint32(26).fork(); + for (var i = 0; i < message.coords.length; ++i) + writer.sint64(message.coords[i]); + writer.ldelim(); + } + return writer; + }; + + Geometry.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Geometry.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + switch (message.geometryType) { + default: + return 'geometryType: enum value expected'; + case 0: + case 1: + case 2: + case 3: + case 4: + case 127: + case 5: + break; + } + if (message.lengths != null && message.hasOwnProperty('lengths')) { + if (!Array.isArray(message.lengths)) return 'lengths: array expected'; + for (var i = 0; i < message.lengths.length; ++i) + if (!$util.isInteger(message.lengths[i])) + return 'lengths: integer[] expected'; + } + if (message.coords != null && message.hasOwnProperty('coords')) { + if (!Array.isArray(message.coords)) return 'coords: array expected'; + for (var i = 0; i < message.coords.length; ++i) + if ( + !$util.isInteger(message.coords[i]) && + !( + message.coords[i] && + $util.isInteger(message.coords[i].low) && + $util.isInteger(message.coords[i].high) + ) + ) + return 'coords: integer|Long[] expected'; + } + return null; + }; + + Geometry.fromObject = function fromObject(object) { + if ( + object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Geometry + ) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Geometry(); + switch (object.geometryType) { + default: + if (typeof object.geometryType === 'number') { + message.geometryType = object.geometryType; + break; } + break; + case 'esriGeometryTypePoint': + case 0: + message.geometryType = 0; + break; + case 'esriGeometryTypeMultipoint': + case 1: + message.geometryType = 1; + break; + case 'esriGeometryTypePolyline': + case 2: + message.geometryType = 2; + break; + case 'esriGeometryTypePolygon': + case 3: + message.geometryType = 3; + break; + case 'esriGeometryTypeMultipatch': + case 4: + message.geometryType = 4; + break; + case 'esriGeometryTypeNone': + case 127: + message.geometryType = 127; + break; + case 'esriGeometryTypeEnvelope': + case 5: + message.geometryType = 5; + break; + } + if (object.lengths) { + if (!Array.isArray(object.lengths)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Geometry.lengths: array expected', + ); + message.lengths = []; + for (var i = 0; i < object.lengths.length; ++i) + message.lengths[i] = object.lengths[i] >>> 0; + } + if (object.coords) { + if (!Array.isArray(object.coords)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Geometry.coords: array expected', + ); + message.coords = []; + for (var i = 0; i < object.coords.length; ++i) + if ($util.Long) + (message.coords[i] = $util.Long.fromValue( + object.coords[i], + )).unsigned = false; + else if (typeof object.coords[i] === 'string') + message.coords[i] = parseInt(object.coords[i], 10); + else if (typeof object.coords[i] === 'number') + message.coords[i] = object.coords[i]; + else if (typeof object.coords[i] === 'object') + message.coords[i] = new $util.LongBits( + object.coords[i].low >>> 0, + object.coords[i].high >>> 0, + ).toNumber(); + } + return message; + }; + + Geometry.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.lengths = []; + object.coords = []; + } + if (options.defaults) + object.geometryType = + options.enums === String ? 'esriGeometryTypePoint' : 0; + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + object.geometryType = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] === undefined + ? message.geometryType + : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] + : message.geometryType; + if (message.lengths && message.lengths.length) { + object.lengths = []; + for (var j = 0; j < message.lengths.length; ++j) + object.lengths[j] = message.lengths[j]; + } + if (message.coords && message.coords.length) { + object.coords = []; + for (var j = 0; j < message.coords.length; ++j) + if (typeof message.coords[j] === 'number') + object.coords[j] = + options.longs === String + ? String(message.coords[j]) + : message.coords[j]; + else + object.coords[j] = + options.longs === String + ? $util.Long.prototype.toString.call(message.coords[j]) + : options.longs === Number + ? new $util.LongBits( + message.coords[j].low >>> 0, + message.coords[j].high >>> 0, + ).toNumber() + : message.coords[j]; + } + return object; + }; - Scale.prototype.xScale = 0; - Scale.prototype.yScale = 0; - Scale.prototype.mScale = 0; - Scale.prototype.zScale = 0; - - Scale.create = function create(properties) { - return new Scale(properties); - }; - - Scale.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.xScale != null && Object.hasOwnProperty.call(message, "xScale")) - writer.uint32(9).double(message.xScale); - if (message.yScale != null && Object.hasOwnProperty.call(message, "yScale")) - writer.uint32(17).double(message.yScale); - if (message.mScale != null && Object.hasOwnProperty.call(message, "mScale")) - writer.uint32(25).double(message.mScale); - if (message.zScale != null && Object.hasOwnProperty.call(message, "zScale")) - writer.uint32(33).double(message.zScale); - return writer; - }; - - Scale.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Scale.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.xScale != null && message.hasOwnProperty("xScale")) - if (typeof message.xScale !== "number") - return "xScale: number expected"; - if (message.yScale != null && message.hasOwnProperty("yScale")) - if (typeof message.yScale !== "number") - return "yScale: number expected"; - if (message.mScale != null && message.hasOwnProperty("mScale")) - if (typeof message.mScale !== "number") - return "mScale: number expected"; - if (message.zScale != null && message.hasOwnProperty("zScale")) - if (typeof message.zScale !== "number") - return "zScale: number expected"; - return null; - }; - - Scale.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Scale) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Scale(); - if (object.xScale != null) - message.xScale = Number(object.xScale); - if (object.yScale != null) - message.yScale = Number(object.yScale); - if (object.mScale != null) - message.mScale = Number(object.mScale); - if (object.zScale != null) - message.zScale = Number(object.zScale); - return message; - }; - - Scale.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.xScale = 0; - object.yScale = 0; - object.mScale = 0; - object.zScale = 0; - } - if (message.xScale != null && message.hasOwnProperty("xScale")) - object.xScale = options.json && !isFinite(message.xScale) ? String(message.xScale) : message.xScale; - if (message.yScale != null && message.hasOwnProperty("yScale")) - object.yScale = options.json && !isFinite(message.yScale) ? String(message.yScale) : message.yScale; - if (message.mScale != null && message.hasOwnProperty("mScale")) - object.mScale = options.json && !isFinite(message.mScale) ? String(message.mScale) : message.mScale; - if (message.zScale != null && message.hasOwnProperty("zScale")) - object.zScale = options.json && !isFinite(message.zScale) ? String(message.zScale) : message.zScale; - return object; - }; - - Scale.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Scale.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Scale"; - }; - - return Scale; - })(); - - FeatureCollectionPBuffer.Translate = (function() { - - function Translate(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + Geometry.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; - Translate.prototype.xTranslate = 0; - Translate.prototype.yTranslate = 0; - Translate.prototype.mTranslate = 0; - Translate.prototype.zTranslate = 0; - - Translate.create = function create(properties) { - return new Translate(properties); - }; - - Translate.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.xTranslate != null && Object.hasOwnProperty.call(message, "xTranslate")) - writer.uint32(9).double(message.xTranslate); - if (message.yTranslate != null && Object.hasOwnProperty.call(message, "yTranslate")) - writer.uint32(17).double(message.yTranslate); - if (message.mTranslate != null && Object.hasOwnProperty.call(message, "mTranslate")) - writer.uint32(25).double(message.mTranslate); - if (message.zTranslate != null && Object.hasOwnProperty.call(message, "zTranslate")) - writer.uint32(33).double(message.zTranslate); - return writer; - }; - - Translate.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Translate.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.xTranslate != null && message.hasOwnProperty("xTranslate")) - if (typeof message.xTranslate !== "number") - return "xTranslate: number expected"; - if (message.yTranslate != null && message.hasOwnProperty("yTranslate")) - if (typeof message.yTranslate !== "number") - return "yTranslate: number expected"; - if (message.mTranslate != null && message.hasOwnProperty("mTranslate")) - if (typeof message.mTranslate !== "number") - return "mTranslate: number expected"; - if (message.zTranslate != null && message.hasOwnProperty("zTranslate")) - if (typeof message.zTranslate !== "number") - return "zTranslate: number expected"; - return null; - }; - - Translate.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Translate) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Translate(); - if (object.xTranslate != null) - message.xTranslate = Number(object.xTranslate); - if (object.yTranslate != null) - message.yTranslate = Number(object.yTranslate); - if (object.mTranslate != null) - message.mTranslate = Number(object.mTranslate); - if (object.zTranslate != null) - message.zTranslate = Number(object.zTranslate); - return message; - }; - - Translate.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.xTranslate = 0; - object.yTranslate = 0; - object.mTranslate = 0; - object.zTranslate = 0; - } - if (message.xTranslate != null && message.hasOwnProperty("xTranslate")) - object.xTranslate = options.json && !isFinite(message.xTranslate) ? String(message.xTranslate) : message.xTranslate; - if (message.yTranslate != null && message.hasOwnProperty("yTranslate")) - object.yTranslate = options.json && !isFinite(message.yTranslate) ? String(message.yTranslate) : message.yTranslate; - if (message.mTranslate != null && message.hasOwnProperty("mTranslate")) - object.mTranslate = options.json && !isFinite(message.mTranslate) ? String(message.mTranslate) : message.mTranslate; - if (message.zTranslate != null && message.hasOwnProperty("zTranslate")) - object.zTranslate = options.json && !isFinite(message.zTranslate) ? String(message.zTranslate) : message.zTranslate; - return object; - }; - - Translate.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Translate.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Translate"; - }; - - return Translate; - })(); - - FeatureCollectionPBuffer.Transform = (function() { - - function Transform(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + Geometry.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Geometry'; + }; - Transform.prototype.quantizeOriginPostion = 0; - Transform.prototype.scale = null; - Transform.prototype.translate = null; - - Transform.create = function create(properties) { - return new Transform(properties); - }; - - Transform.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.quantizeOriginPostion != null && Object.hasOwnProperty.call(message, "quantizeOriginPostion")) - writer.uint32(8).int32(message.quantizeOriginPostion); - if (message.scale != null && Object.hasOwnProperty.call(message, "scale")) - $root.esriPBuffer.FeatureCollectionPBuffer.Scale.encode(message.scale, writer.uint32(18).fork()).ldelim(); - if (message.translate != null && Object.hasOwnProperty.call(message, "translate")) - $root.esriPBuffer.FeatureCollectionPBuffer.Translate.encode(message.translate, writer.uint32(26).fork()).ldelim(); - return writer; - }; - - Transform.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - Transform.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.quantizeOriginPostion != null && message.hasOwnProperty("quantizeOriginPostion")) - switch (message.quantizeOriginPostion) { - default: - return "quantizeOriginPostion: enum value expected"; - case 0: - case 1: - break; - } - if (message.scale != null && message.hasOwnProperty("scale")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Scale.verify(message.scale); - if (error) - return "scale." + error; - } - if (message.translate != null && message.hasOwnProperty("translate")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Translate.verify(message.translate); - if (error) - return "translate." + error; - } - return null; - }; - - Transform.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Transform) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Transform(); - switch (object.quantizeOriginPostion) { - default: - if (typeof object.quantizeOriginPostion === "number") { - message.quantizeOriginPostion = object.quantizeOriginPostion; - break; - } - break; - case "upperLeft": - case 0: - message.quantizeOriginPostion = 0; - break; - case "lowerLeft": - case 1: - message.quantizeOriginPostion = 1; - break; - } - if (object.scale != null) { - if (typeof object.scale !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Transform.scale: object expected"); - message.scale = $root.esriPBuffer.FeatureCollectionPBuffer.Scale.fromObject(object.scale); - } - if (object.translate != null) { - if (typeof object.translate !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.Transform.translate: object expected"); - message.translate = $root.esriPBuffer.FeatureCollectionPBuffer.Translate.fromObject(object.translate); - } - return message; - }; - - Transform.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) { - object.quantizeOriginPostion = options.enums === String ? "upperLeft" : 0; - object.scale = null; - object.translate = null; - } - if (message.quantizeOriginPostion != null && message.hasOwnProperty("quantizeOriginPostion")) - object.quantizeOriginPostion = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.QuantizeOriginPostion[message.quantizeOriginPostion] === undefined ? message.quantizeOriginPostion : $root.esriPBuffer.FeatureCollectionPBuffer.QuantizeOriginPostion[message.quantizeOriginPostion] : message.quantizeOriginPostion; - if (message.scale != null && message.hasOwnProperty("scale")) - object.scale = $root.esriPBuffer.FeatureCollectionPBuffer.Scale.toObject(message.scale, options); - if (message.translate != null && message.hasOwnProperty("translate")) - object.translate = $root.esriPBuffer.FeatureCollectionPBuffer.Translate.toObject(message.translate, options); - return object; - }; - - Transform.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - Transform.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.Transform"; - }; - - return Transform; - })(); - - FeatureCollectionPBuffer.FeatureResult = (function() { - - function FeatureResult(properties) { - this.fields = []; - this.values = []; - this.features = []; - this.geometryFields = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + return Geometry; + })(); - FeatureResult.prototype.objectIdFieldName = ""; - FeatureResult.prototype.uniqueIdField = null; - FeatureResult.prototype.globalIdFieldName = ""; - FeatureResult.prototype.geohashFieldName = ""; - FeatureResult.prototype.geometryProperties = null; - FeatureResult.prototype.serverGens = null; - FeatureResult.prototype.geometryType = 0; - FeatureResult.prototype.spatialReference = null; - FeatureResult.prototype.exceededTransferLimit = false; - FeatureResult.prototype.hasZ = false; - FeatureResult.prototype.hasM = false; - FeatureResult.prototype.transform = null; - FeatureResult.prototype.fields = $util.emptyArray; - FeatureResult.prototype.values = $util.emptyArray; - FeatureResult.prototype.features = $util.emptyArray; - FeatureResult.prototype.geometryFields = $util.emptyArray; - - FeatureResult.create = function create(properties) { - return new FeatureResult(properties); - }; - - FeatureResult.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.objectIdFieldName != null && Object.hasOwnProperty.call(message, "objectIdFieldName")) - writer.uint32(10).string(message.objectIdFieldName); - if (message.uniqueIdField != null && Object.hasOwnProperty.call(message, "uniqueIdField")) - $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.encode(message.uniqueIdField, writer.uint32(18).fork()).ldelim(); - if (message.globalIdFieldName != null && Object.hasOwnProperty.call(message, "globalIdFieldName")) - writer.uint32(26).string(message.globalIdFieldName); - if (message.geohashFieldName != null && Object.hasOwnProperty.call(message, "geohashFieldName")) - writer.uint32(34).string(message.geohashFieldName); - if (message.geometryProperties != null && Object.hasOwnProperty.call(message, "geometryProperties")) - $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.encode(message.geometryProperties, writer.uint32(42).fork()).ldelim(); - if (message.serverGens != null && Object.hasOwnProperty.call(message, "serverGens")) - $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.encode(message.serverGens, writer.uint32(50).fork()).ldelim(); - if (message.geometryType != null && Object.hasOwnProperty.call(message, "geometryType")) - writer.uint32(56).int32(message.geometryType); - if (message.spatialReference != null && Object.hasOwnProperty.call(message, "spatialReference")) - $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.encode(message.spatialReference, writer.uint32(66).fork()).ldelim(); - if (message.exceededTransferLimit != null && Object.hasOwnProperty.call(message, "exceededTransferLimit")) - writer.uint32(72).bool(message.exceededTransferLimit); - if (message.hasZ != null && Object.hasOwnProperty.call(message, "hasZ")) - writer.uint32(80).bool(message.hasZ); - if (message.hasM != null && Object.hasOwnProperty.call(message, "hasM")) - writer.uint32(88).bool(message.hasM); - if (message.transform != null && Object.hasOwnProperty.call(message, "transform")) - $root.esriPBuffer.FeatureCollectionPBuffer.Transform.encode(message.transform, writer.uint32(98).fork()).ldelim(); - if (message.fields != null && message.fields.length) - for (var i = 0; i < message.fields.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.Field.encode(message.fields[i], writer.uint32(106).fork()).ldelim(); - if (message.values != null && message.values.length) - for (var i = 0; i < message.values.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.Value.encode(message.values[i], writer.uint32(114).fork()).ldelim(); - if (message.features != null && message.features.length) - for (var i = 0; i < message.features.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.Feature.encode(message.features[i], writer.uint32(122).fork()).ldelim(); - if (message.geometryFields != null && message.geometryFields.length) - for (var i = 0; i < message.geometryFields.length; ++i) - $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.encode(message.geometryFields[i], writer.uint32(130).fork()).ldelim(); - return writer; - }; - - FeatureResult.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - FeatureResult.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.objectIdFieldName != null && message.hasOwnProperty("objectIdFieldName")) - if (!$util.isString(message.objectIdFieldName)) - return "objectIdFieldName: string expected"; - if (message.uniqueIdField != null && message.hasOwnProperty("uniqueIdField")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.verify(message.uniqueIdField); - if (error) - return "uniqueIdField." + error; - } - if (message.globalIdFieldName != null && message.hasOwnProperty("globalIdFieldName")) - if (!$util.isString(message.globalIdFieldName)) - return "globalIdFieldName: string expected"; - if (message.geohashFieldName != null && message.hasOwnProperty("geohashFieldName")) - if (!$util.isString(message.geohashFieldName)) - return "geohashFieldName: string expected"; - if (message.geometryProperties != null && message.hasOwnProperty("geometryProperties")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.verify(message.geometryProperties); - if (error) - return "geometryProperties." + error; - } - if (message.serverGens != null && message.hasOwnProperty("serverGens")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.verify(message.serverGens); - if (error) - return "serverGens." + error; - } - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - switch (message.geometryType) { - default: - return "geometryType: enum value expected"; - case 0: - case 1: - case 2: - case 3: - case 4: - case 127: - case 5: - break; - } - if (message.spatialReference != null && message.hasOwnProperty("spatialReference")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.verify(message.spatialReference); - if (error) - return "spatialReference." + error; - } - if (message.exceededTransferLimit != null && message.hasOwnProperty("exceededTransferLimit")) - if (typeof message.exceededTransferLimit !== "boolean") - return "exceededTransferLimit: boolean expected"; - if (message.hasZ != null && message.hasOwnProperty("hasZ")) - if (typeof message.hasZ !== "boolean") - return "hasZ: boolean expected"; - if (message.hasM != null && message.hasOwnProperty("hasM")) - if (typeof message.hasM !== "boolean") - return "hasM: boolean expected"; - if (message.transform != null && message.hasOwnProperty("transform")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Transform.verify(message.transform); - if (error) - return "transform." + error; - } - if (message.fields != null && message.hasOwnProperty("fields")) { - if (!Array.isArray(message.fields)) - return "fields: array expected"; - for (var i = 0; i < message.fields.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Field.verify(message.fields[i]); - if (error) - return "fields." + error; - } - } - if (message.values != null && message.hasOwnProperty("values")) { - if (!Array.isArray(message.values)) - return "values: array expected"; - for (var i = 0; i < message.values.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Value.verify(message.values[i]); - if (error) - return "values." + error; - } - } - if (message.features != null && message.hasOwnProperty("features")) { - if (!Array.isArray(message.features)) - return "features: array expected"; - for (var i = 0; i < message.features.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.Feature.verify(message.features[i]); - if (error) - return "features." + error; - } - } - if (message.geometryFields != null && message.hasOwnProperty("geometryFields")) { - if (!Array.isArray(message.geometryFields)) - return "geometryFields: array expected"; - for (var i = 0; i < message.geometryFields.length; ++i) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.verify(message.geometryFields[i]); - if (error) - return "geometryFields." + error; - } - } - return null; - }; - - FeatureResult.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult(); - if (object.objectIdFieldName != null) - message.objectIdFieldName = String(object.objectIdFieldName); - if (object.uniqueIdField != null) { - if (typeof object.uniqueIdField !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.uniqueIdField: object expected"); - message.uniqueIdField = $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.fromObject(object.uniqueIdField); - } - if (object.globalIdFieldName != null) - message.globalIdFieldName = String(object.globalIdFieldName); - if (object.geohashFieldName != null) - message.geohashFieldName = String(object.geohashFieldName); - if (object.geometryProperties != null) { - if (typeof object.geometryProperties !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryProperties: object expected"); - message.geometryProperties = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.fromObject(object.geometryProperties); - } - if (object.serverGens != null) { - if (typeof object.serverGens !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.serverGens: object expected"); - message.serverGens = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.fromObject(object.serverGens); - } - switch (object.geometryType) { - default: - if (typeof object.geometryType === "number") { - message.geometryType = object.geometryType; - break; - } - break; - case "esriGeometryTypePoint": - case 0: - message.geometryType = 0; - break; - case "esriGeometryTypeMultipoint": - case 1: - message.geometryType = 1; - break; - case "esriGeometryTypePolyline": - case 2: - message.geometryType = 2; - break; - case "esriGeometryTypePolygon": - case 3: - message.geometryType = 3; - break; - case "esriGeometryTypeMultipatch": - case 4: - message.geometryType = 4; - break; - case "esriGeometryTypeNone": - case 127: - message.geometryType = 127; - break; - case "esriGeometryTypeEnvelope": - case 5: - message.geometryType = 5; - break; - } - if (object.spatialReference != null) { - if (typeof object.spatialReference !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.spatialReference: object expected"); - message.spatialReference = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.fromObject(object.spatialReference); - } - if (object.exceededTransferLimit != null) - message.exceededTransferLimit = Boolean(object.exceededTransferLimit); - if (object.hasZ != null) - message.hasZ = Boolean(object.hasZ); - if (object.hasM != null) - message.hasM = Boolean(object.hasM); - if (object.transform != null) { - if (typeof object.transform !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.transform: object expected"); - message.transform = $root.esriPBuffer.FeatureCollectionPBuffer.Transform.fromObject(object.transform); - } - if (object.fields) { - if (!Array.isArray(object.fields)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fields: array expected"); - message.fields = []; - for (var i = 0; i < object.fields.length; ++i) { - if (typeof object.fields[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fields: object expected"); - message.fields[i] = $root.esriPBuffer.FeatureCollectionPBuffer.Field.fromObject(object.fields[i]); - } - } - if (object.values) { - if (!Array.isArray(object.values)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.values: array expected"); - message.values = []; - for (var i = 0; i < object.values.length; ++i) { - if (typeof object.values[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.values: object expected"); - message.values[i] = $root.esriPBuffer.FeatureCollectionPBuffer.Value.fromObject(object.values[i]); - } - } - if (object.features) { - if (!Array.isArray(object.features)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.features: array expected"); - message.features = []; - for (var i = 0; i < object.features.length; ++i) { - if (typeof object.features[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.features: object expected"); - message.features[i] = $root.esriPBuffer.FeatureCollectionPBuffer.Feature.fromObject(object.features[i]); - } - } - if (object.geometryFields) { - if (!Array.isArray(object.geometryFields)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryFields: array expected"); - message.geometryFields = []; - for (var i = 0; i < object.geometryFields.length; ++i) { - if (typeof object.geometryFields[i] !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryFields: object expected"); - message.geometryFields[i] = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.fromObject(object.geometryFields[i]); - } - } - return message; - }; - - FeatureResult.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) { - object.fields = []; - object.values = []; - object.features = []; - object.geometryFields = []; - } - if (options.defaults) { - object.objectIdFieldName = ""; - object.uniqueIdField = null; - object.globalIdFieldName = ""; - object.geohashFieldName = ""; - object.geometryProperties = null; - object.serverGens = null; - object.geometryType = options.enums === String ? "esriGeometryTypePoint" : 0; - object.spatialReference = null; - object.exceededTransferLimit = false; - object.hasZ = false; - object.hasM = false; - object.transform = null; - } - if (message.objectIdFieldName != null && message.hasOwnProperty("objectIdFieldName")) - object.objectIdFieldName = message.objectIdFieldName; - if (message.uniqueIdField != null && message.hasOwnProperty("uniqueIdField")) - object.uniqueIdField = $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.toObject(message.uniqueIdField, options); - if (message.globalIdFieldName != null && message.hasOwnProperty("globalIdFieldName")) - object.globalIdFieldName = message.globalIdFieldName; - if (message.geohashFieldName != null && message.hasOwnProperty("geohashFieldName")) - object.geohashFieldName = message.geohashFieldName; - if (message.geometryProperties != null && message.hasOwnProperty("geometryProperties")) - object.geometryProperties = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.toObject(message.geometryProperties, options); - if (message.serverGens != null && message.hasOwnProperty("serverGens")) - object.serverGens = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.toObject(message.serverGens, options); - if (message.geometryType != null && message.hasOwnProperty("geometryType")) - object.geometryType = options.enums === String ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] === undefined ? message.geometryType : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[message.geometryType] : message.geometryType; - if (message.spatialReference != null && message.hasOwnProperty("spatialReference")) - object.spatialReference = $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.toObject(message.spatialReference, options); - if (message.exceededTransferLimit != null && message.hasOwnProperty("exceededTransferLimit")) - object.exceededTransferLimit = message.exceededTransferLimit; - if (message.hasZ != null && message.hasOwnProperty("hasZ")) - object.hasZ = message.hasZ; - if (message.hasM != null && message.hasOwnProperty("hasM")) - object.hasM = message.hasM; - if (message.transform != null && message.hasOwnProperty("transform")) - object.transform = $root.esriPBuffer.FeatureCollectionPBuffer.Transform.toObject(message.transform, options); - if (message.fields && message.fields.length) { - object.fields = []; - for (var j = 0; j < message.fields.length; ++j) - object.fields[j] = $root.esriPBuffer.FeatureCollectionPBuffer.Field.toObject(message.fields[j], options); - } - if (message.values && message.values.length) { - object.values = []; - for (var j = 0; j < message.values.length; ++j) - object.values[j] = $root.esriPBuffer.FeatureCollectionPBuffer.Value.toObject(message.values[j], options); - } - if (message.features && message.features.length) { - object.features = []; - for (var j = 0; j < message.features.length; ++j) - object.features[j] = $root.esriPBuffer.FeatureCollectionPBuffer.Feature.toObject(message.features[j], options); - } - if (message.geometryFields && message.geometryFields.length) { - object.geometryFields = []; - for (var j = 0; j < message.geometryFields.length; ++j) - object.geometryFields[j] = $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.toObject(message.geometryFields[j], options); - } - return object; - }; - - FeatureResult.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - FeatureResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.FeatureResult"; - }; - - return FeatureResult; - })(); - - FeatureCollectionPBuffer.CountResult = (function() { - - function CountResult(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; - } + FeatureCollectionPBuffer.esriShapeBuffer = (function () { + function esriShapeBuffer(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + esriShapeBuffer.prototype.bytes = $util.newBuffer([]); + + esriShapeBuffer.create = function create(properties) { + return new esriShapeBuffer(properties); + }; + + esriShapeBuffer.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.bytes != null && + Object.hasOwnProperty.call(message, 'bytes') + ) + writer.uint32(10).bytes(message.bytes); + return writer; + }; + + esriShapeBuffer.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + esriShapeBuffer.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.bytes != null && message.hasOwnProperty('bytes')) + if ( + !( + (message.bytes && typeof message.bytes.length === 'number') || + $util.isString(message.bytes) + ) + ) + return 'bytes: buffer expected'; + return null; + }; + + esriShapeBuffer.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer(); + if (object.bytes != null) + if (typeof object.bytes === 'string') + $util.base64.decode( + object.bytes, + (message.bytes = $util.newBuffer( + $util.base64.length(object.bytes), + )), + 0, + ); + else if (object.bytes.length >= 0) message.bytes = object.bytes; + return message; + }; + + esriShapeBuffer.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) + if (options.bytes === String) object.bytes = ''; + else { + object.bytes = []; + if (options.bytes !== Array) + object.bytes = $util.newBuffer(object.bytes); + } + if (message.bytes != null && message.hasOwnProperty('bytes')) + object.bytes = + options.bytes === String + ? $util.base64.encode(message.bytes, 0, message.bytes.length) + : options.bytes === Array + ? Array.prototype.slice.call(message.bytes) + : message.bytes; + return object; + }; + + esriShapeBuffer.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + esriShapeBuffer.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + + '/esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer' + ); + }; + + return esriShapeBuffer; + })(); + + FeatureCollectionPBuffer.Feature = (function () { + function Feature(properties) { + this.attributes = []; + this.aggregateGeometries = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Feature.prototype.attributes = $util.emptyArray; + Feature.prototype.geometry = null; + Feature.prototype.shapeBuffer = null; + Feature.prototype.centroid = null; + Feature.prototype.aggregateGeometries = $util.emptyArray; + Feature.prototype.envelope = null; + + var $oneOfFields; + + Object.defineProperty(Feature.prototype, 'compressedGeometry', { + get: $util.oneOfGetter(($oneOfFields = ['geometry', 'shapeBuffer'])), + set: $util.oneOfSetter($oneOfFields), + }); + + Feature.create = function create(properties) { + return new Feature(properties); + }; + + Feature.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.attributes != null && message.attributes.length) + for (var i = 0; i < message.attributes.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.Value.encode( + message.attributes[i], + writer.uint32(10).fork(), + ).ldelim(); + if ( + message.geometry != null && + Object.hasOwnProperty.call(message, 'geometry') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode( + message.geometry, + writer.uint32(18).fork(), + ).ldelim(); + if ( + message.shapeBuffer != null && + Object.hasOwnProperty.call(message, 'shapeBuffer') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer + .encode(message.shapeBuffer, writer.uint32(26).fork()) + .ldelim(); + if ( + message.centroid != null && + Object.hasOwnProperty.call(message, 'centroid') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode( + message.centroid, + writer.uint32(34).fork(), + ).ldelim(); + if ( + message.aggregateGeometries != null && + message.aggregateGeometries.length + ) + for (var i = 0; i < message.aggregateGeometries.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.encode( + message.aggregateGeometries[i], + writer.uint32(42).fork(), + ).ldelim(); + if ( + message.envelope != null && + Object.hasOwnProperty.call(message, 'envelope') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.encode( + message.envelope, + writer.uint32(50).fork(), + ).ldelim(); + return writer; + }; + + Feature.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Feature.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + var properties = {}; + if ( + message.attributes != null && + message.hasOwnProperty('attributes') + ) { + if (!Array.isArray(message.attributes)) + return 'attributes: array expected'; + for (var i = 0; i < message.attributes.length; ++i) { + var error = $root.esriPBuffer.FeatureCollectionPBuffer.Value.verify( + message.attributes[i], + ); + if (error) return 'attributes.' + error; + } + } + if (message.geometry != null && message.hasOwnProperty('geometry')) { + properties.compressedGeometry = 1; + { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify( + message.geometry, + ); + if (error) return 'geometry.' + error; + } + } + if ( + message.shapeBuffer != null && + message.hasOwnProperty('shapeBuffer') + ) { + if (properties.compressedGeometry === 1) + return 'compressedGeometry: multiple values'; + properties.compressedGeometry = 1; + { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.verify( + message.shapeBuffer, + ); + if (error) return 'shapeBuffer.' + error; + } + } + if (message.centroid != null && message.hasOwnProperty('centroid')) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify( + message.centroid, + ); + if (error) return 'centroid.' + error; + } + if ( + message.aggregateGeometries != null && + message.hasOwnProperty('aggregateGeometries') + ) { + if (!Array.isArray(message.aggregateGeometries)) + return 'aggregateGeometries: array expected'; + for (var i = 0; i < message.aggregateGeometries.length; ++i) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.verify( + message.aggregateGeometries[i], + ); + if (error) return 'aggregateGeometries.' + error; + } + } + if (message.envelope != null && message.hasOwnProperty('envelope')) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.verify( + message.envelope, + ); + if (error) return 'envelope.' + error; + } + return null; + }; + + Feature.fromObject = function fromObject(object) { + if ( + object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Feature + ) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Feature(); + if (object.attributes) { + if (!Array.isArray(object.attributes)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.attributes: array expected', + ); + message.attributes = []; + for (var i = 0; i < object.attributes.length; ++i) { + if (typeof object.attributes[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.attributes: object expected', + ); + message.attributes[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.Value.fromObject( + object.attributes[i], + ); + } + } + if (object.geometry != null) { + if (typeof object.geometry !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.geometry: object expected', + ); + message.geometry = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject( + object.geometry, + ); + } + if (object.shapeBuffer != null) { + if (typeof object.shapeBuffer !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.shapeBuffer: object expected', + ); + message.shapeBuffer = + $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.fromObject( + object.shapeBuffer, + ); + } + if (object.centroid != null) { + if (typeof object.centroid !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.centroid: object expected', + ); + message.centroid = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject( + object.centroid, + ); + } + if (object.aggregateGeometries) { + if (!Array.isArray(object.aggregateGeometries)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.aggregateGeometries: array expected', + ); + message.aggregateGeometries = []; + for (var i = 0; i < object.aggregateGeometries.length; ++i) { + if (typeof object.aggregateGeometries[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.aggregateGeometries: object expected', + ); + message.aggregateGeometries[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.fromObject( + object.aggregateGeometries[i], + ); + } + } + if (object.envelope != null) { + if (typeof object.envelope !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Feature.envelope: object expected', + ); + message.envelope = + $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.fromObject( + object.envelope, + ); + } + return message; + }; + + Feature.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.attributes = []; + object.aggregateGeometries = []; + } + if (options.defaults) { + object.centroid = null; + object.envelope = null; + } + if (message.attributes && message.attributes.length) { + object.attributes = []; + for (var j = 0; j < message.attributes.length; ++j) + object.attributes[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.Value.toObject( + message.attributes[j], + options, + ); + } + if (message.geometry != null && message.hasOwnProperty('geometry')) { + object.geometry = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject( + message.geometry, + options, + ); + if (options.oneofs) object.compressedGeometry = 'geometry'; + } + if ( + message.shapeBuffer != null && + message.hasOwnProperty('shapeBuffer') + ) { + object.shapeBuffer = + $root.esriPBuffer.FeatureCollectionPBuffer.esriShapeBuffer.toObject( + message.shapeBuffer, + options, + ); + if (options.oneofs) object.compressedGeometry = 'shapeBuffer'; + } + if (message.centroid != null && message.hasOwnProperty('centroid')) + object.centroid = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject( + message.centroid, + options, + ); + if (message.aggregateGeometries && message.aggregateGeometries.length) { + object.aggregateGeometries = []; + for (var j = 0; j < message.aggregateGeometries.length; ++j) + object.aggregateGeometries[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.Geometry.toObject( + message.aggregateGeometries[j], + options, + ); + } + if (message.envelope != null && message.hasOwnProperty('envelope')) + object.envelope = + $root.esriPBuffer.FeatureCollectionPBuffer.Envelope.toObject( + message.envelope, + options, + ); + return object; + }; + + Feature.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Feature.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Feature'; + }; + + return Feature; + })(); + + FeatureCollectionPBuffer.UniqueIdField = (function () { + function UniqueIdField(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + UniqueIdField.prototype.name = ''; + UniqueIdField.prototype.isSystemMaintained = false; + + UniqueIdField.create = function create(properties) { + return new UniqueIdField(properties); + }; + + UniqueIdField.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if (message.name != null && Object.hasOwnProperty.call(message, 'name')) + writer.uint32(10).string(message.name); + if ( + message.isSystemMaintained != null && + Object.hasOwnProperty.call(message, 'isSystemMaintained') + ) + writer.uint32(16).bool(message.isSystemMaintained); + return writer; + }; + + UniqueIdField.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + UniqueIdField.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.name != null && message.hasOwnProperty('name')) + if (!$util.isString(message.name)) return 'name: string expected'; + if ( + message.isSystemMaintained != null && + message.hasOwnProperty('isSystemMaintained') + ) + if (typeof message.isSystemMaintained !== 'boolean') + return 'isSystemMaintained: boolean expected'; + return null; + }; + + UniqueIdField.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField(); + if (object.name != null) message.name = String(object.name); + if (object.isSystemMaintained != null) + message.isSystemMaintained = Boolean(object.isSystemMaintained); + return message; + }; + + UniqueIdField.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.name = ''; + object.isSystemMaintained = false; + } + if (message.name != null && message.hasOwnProperty('name')) + object.name = message.name; + if ( + message.isSystemMaintained != null && + message.hasOwnProperty('isSystemMaintained') + ) + object.isSystemMaintained = message.isSystemMaintained; + return object; + }; + + UniqueIdField.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + UniqueIdField.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.UniqueIdField' + ); + }; + + return UniqueIdField; + })(); + + FeatureCollectionPBuffer.GeometryProperties = (function () { + function GeometryProperties(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + GeometryProperties.prototype.shapeAreaFieldName = ''; + GeometryProperties.prototype.shapeLengthFieldName = ''; + GeometryProperties.prototype.units = ''; + + GeometryProperties.create = function create(properties) { + return new GeometryProperties(properties); + }; + + GeometryProperties.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.shapeAreaFieldName != null && + Object.hasOwnProperty.call(message, 'shapeAreaFieldName') + ) + writer.uint32(10).string(message.shapeAreaFieldName); + if ( + message.shapeLengthFieldName != null && + Object.hasOwnProperty.call(message, 'shapeLengthFieldName') + ) + writer.uint32(18).string(message.shapeLengthFieldName); + if ( + message.units != null && + Object.hasOwnProperty.call(message, 'units') + ) + writer.uint32(26).string(message.units); + return writer; + }; + + GeometryProperties.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + GeometryProperties.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.shapeAreaFieldName != null && + message.hasOwnProperty('shapeAreaFieldName') + ) + if (!$util.isString(message.shapeAreaFieldName)) + return 'shapeAreaFieldName: string expected'; + if ( + message.shapeLengthFieldName != null && + message.hasOwnProperty('shapeLengthFieldName') + ) + if (!$util.isString(message.shapeLengthFieldName)) + return 'shapeLengthFieldName: string expected'; + if (message.units != null && message.hasOwnProperty('units')) + if (!$util.isString(message.units)) return 'units: string expected'; + return null; + }; + + GeometryProperties.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties(); + if (object.shapeAreaFieldName != null) + message.shapeAreaFieldName = String(object.shapeAreaFieldName); + if (object.shapeLengthFieldName != null) + message.shapeLengthFieldName = String(object.shapeLengthFieldName); + if (object.units != null) message.units = String(object.units); + return message; + }; + + GeometryProperties.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.shapeAreaFieldName = ''; + object.shapeLengthFieldName = ''; + object.units = ''; + } + if ( + message.shapeAreaFieldName != null && + message.hasOwnProperty('shapeAreaFieldName') + ) + object.shapeAreaFieldName = message.shapeAreaFieldName; + if ( + message.shapeLengthFieldName != null && + message.hasOwnProperty('shapeLengthFieldName') + ) + object.shapeLengthFieldName = message.shapeLengthFieldName; + if (message.units != null && message.hasOwnProperty('units')) + object.units = message.units; + return object; + }; + + GeometryProperties.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + GeometryProperties.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + + '/esriPBuffer.FeatureCollectionPBuffer.GeometryProperties' + ); + }; + + return GeometryProperties; + })(); + + FeatureCollectionPBuffer.ServerGens = (function () { + function ServerGens(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + ServerGens.prototype.minServerGen = $util.Long + ? $util.Long.fromBits(0, 0, true) + : 0; + ServerGens.prototype.serverGen = $util.Long + ? $util.Long.fromBits(0, 0, true) + : 0; + + ServerGens.create = function create(properties) { + return new ServerGens(properties); + }; + + ServerGens.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.minServerGen != null && + Object.hasOwnProperty.call(message, 'minServerGen') + ) + writer.uint32(8).uint64(message.minServerGen); + if ( + message.serverGen != null && + Object.hasOwnProperty.call(message, 'serverGen') + ) + writer.uint32(16).uint64(message.serverGen); + return writer; + }; + + ServerGens.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + ServerGens.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.minServerGen != null && + message.hasOwnProperty('minServerGen') + ) + if ( + !$util.isInteger(message.minServerGen) && + !( + message.minServerGen && + $util.isInteger(message.minServerGen.low) && + $util.isInteger(message.minServerGen.high) + ) + ) + return 'minServerGen: integer|Long expected'; + if (message.serverGen != null && message.hasOwnProperty('serverGen')) + if ( + !$util.isInteger(message.serverGen) && + !( + message.serverGen && + $util.isInteger(message.serverGen.low) && + $util.isInteger(message.serverGen.high) + ) + ) + return 'serverGen: integer|Long expected'; + return null; + }; + + ServerGens.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens(); + if (object.minServerGen != null) + if ($util.Long) + (message.minServerGen = $util.Long.fromValue( + object.minServerGen, + )).unsigned = true; + else if (typeof object.minServerGen === 'string') + message.minServerGen = parseInt(object.minServerGen, 10); + else if (typeof object.minServerGen === 'number') + message.minServerGen = object.minServerGen; + else if (typeof object.minServerGen === 'object') + message.minServerGen = new $util.LongBits( + object.minServerGen.low >>> 0, + object.minServerGen.high >>> 0, + ).toNumber(true); + if (object.serverGen != null) + if ($util.Long) + (message.serverGen = $util.Long.fromValue( + object.serverGen, + )).unsigned = true; + else if (typeof object.serverGen === 'string') + message.serverGen = parseInt(object.serverGen, 10); + else if (typeof object.serverGen === 'number') + message.serverGen = object.serverGen; + else if (typeof object.serverGen === 'object') + message.serverGen = new $util.LongBits( + object.serverGen.low >>> 0, + object.serverGen.high >>> 0, + ).toNumber(true); + return message; + }; + + ServerGens.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.minServerGen = + options.longs === String + ? long.toString() + : options.longs === Number + ? long.toNumber() + : long; + } else object.minServerGen = options.longs === String ? '0' : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.serverGen = + options.longs === String + ? long.toString() + : options.longs === Number + ? long.toNumber() + : long; + } else object.serverGen = options.longs === String ? '0' : 0; + } + if ( + message.minServerGen != null && + message.hasOwnProperty('minServerGen') + ) + if (typeof message.minServerGen === 'number') + object.minServerGen = + options.longs === String + ? String(message.minServerGen) + : message.minServerGen; + else + object.minServerGen = + options.longs === String + ? $util.Long.prototype.toString.call(message.minServerGen) + : options.longs === Number + ? new $util.LongBits( + message.minServerGen.low >>> 0, + message.minServerGen.high >>> 0, + ).toNumber(true) + : message.minServerGen; + if (message.serverGen != null && message.hasOwnProperty('serverGen')) + if (typeof message.serverGen === 'number') + object.serverGen = + options.longs === String + ? String(message.serverGen) + : message.serverGen; + else + object.serverGen = + options.longs === String + ? $util.Long.prototype.toString.call(message.serverGen) + : options.longs === Number + ? new $util.LongBits( + message.serverGen.low >>> 0, + message.serverGen.high >>> 0, + ).toNumber(true) + : message.serverGen; + return object; + }; + + ServerGens.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + ServerGens.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.ServerGens' + ); + }; + + return ServerGens; + })(); + + FeatureCollectionPBuffer.Scale = (function () { + function Scale(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Scale.prototype.xScale = 0; + Scale.prototype.yScale = 0; + Scale.prototype.mScale = 0; + Scale.prototype.zScale = 0; + + Scale.create = function create(properties) { + return new Scale(properties); + }; + + Scale.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.xScale != null && + Object.hasOwnProperty.call(message, 'xScale') + ) + writer.uint32(9).double(message.xScale); + if ( + message.yScale != null && + Object.hasOwnProperty.call(message, 'yScale') + ) + writer.uint32(17).double(message.yScale); + if ( + message.mScale != null && + Object.hasOwnProperty.call(message, 'mScale') + ) + writer.uint32(25).double(message.mScale); + if ( + message.zScale != null && + Object.hasOwnProperty.call(message, 'zScale') + ) + writer.uint32(33).double(message.zScale); + return writer; + }; + + Scale.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Scale.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.xScale != null && message.hasOwnProperty('xScale')) + if (typeof message.xScale !== 'number') + return 'xScale: number expected'; + if (message.yScale != null && message.hasOwnProperty('yScale')) + if (typeof message.yScale !== 'number') + return 'yScale: number expected'; + if (message.mScale != null && message.hasOwnProperty('mScale')) + if (typeof message.mScale !== 'number') + return 'mScale: number expected'; + if (message.zScale != null && message.hasOwnProperty('zScale')) + if (typeof message.zScale !== 'number') + return 'zScale: number expected'; + return null; + }; + + Scale.fromObject = function fromObject(object) { + if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Scale) + return object; + var message = new $root.esriPBuffer.FeatureCollectionPBuffer.Scale(); + if (object.xScale != null) message.xScale = Number(object.xScale); + if (object.yScale != null) message.yScale = Number(object.yScale); + if (object.mScale != null) message.mScale = Number(object.mScale); + if (object.zScale != null) message.zScale = Number(object.zScale); + return message; + }; + + Scale.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.xScale = 0; + object.yScale = 0; + object.mScale = 0; + object.zScale = 0; + } + if (message.xScale != null && message.hasOwnProperty('xScale')) + object.xScale = + options.json && !isFinite(message.xScale) + ? String(message.xScale) + : message.xScale; + if (message.yScale != null && message.hasOwnProperty('yScale')) + object.yScale = + options.json && !isFinite(message.yScale) + ? String(message.yScale) + : message.yScale; + if (message.mScale != null && message.hasOwnProperty('mScale')) + object.mScale = + options.json && !isFinite(message.mScale) + ? String(message.mScale) + : message.mScale; + if (message.zScale != null && message.hasOwnProperty('zScale')) + object.zScale = + options.json && !isFinite(message.zScale) + ? String(message.zScale) + : message.zScale; + return object; + }; + + Scale.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Scale.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Scale'; + }; - CountResult.prototype.count = $util.Long ? $util.Long.fromBits(0,0,true) : 0; - - CountResult.create = function create(properties) { - return new CountResult(properties); - }; - - CountResult.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.count != null && Object.hasOwnProperty.call(message, "count")) - writer.uint32(8).uint64(message.count); - return writer; - }; - - CountResult.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - CountResult.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.count != null && message.hasOwnProperty("count")) - if (!$util.isInteger(message.count) && !(message.count && $util.isInteger(message.count.low) && $util.isInteger(message.count.high))) - return "count: integer|Long expected"; - return null; - }; - - CountResult.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.CountResult) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.CountResult(); - if (object.count != null) - if ($util.Long) - (message.count = $util.Long.fromValue(object.count)).unsigned = true; - else if (typeof object.count === "string") - message.count = parseInt(object.count, 10); - else if (typeof object.count === "number") - message.count = object.count; - else if (typeof object.count === "object") - message.count = new $util.LongBits(object.count.low >>> 0, object.count.high >>> 0).toNumber(true); - return message; - }; - - CountResult.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.defaults) - if ($util.Long) { - var long = new $util.Long(0, 0, true); - object.count = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; - } else - object.count = options.longs === String ? "0" : 0; - if (message.count != null && message.hasOwnProperty("count")) - if (typeof message.count === "number") - object.count = options.longs === String ? String(message.count) : message.count; - else - object.count = options.longs === String ? $util.Long.prototype.toString.call(message.count) : options.longs === Number ? new $util.LongBits(message.count.low >>> 0, message.count.high >>> 0).toNumber(true) : message.count; - return object; - }; - - CountResult.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - CountResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.CountResult"; - }; - - return CountResult; - })(); - - FeatureCollectionPBuffer.ObjectIdsResult = (function() { - - function ObjectIdsResult(properties) { - this.objectIds = []; - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; + return Scale; + })(); + + FeatureCollectionPBuffer.Translate = (function () { + function Translate(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Translate.prototype.xTranslate = 0; + Translate.prototype.yTranslate = 0; + Translate.prototype.mTranslate = 0; + Translate.prototype.zTranslate = 0; + + Translate.create = function create(properties) { + return new Translate(properties); + }; + + Translate.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.xTranslate != null && + Object.hasOwnProperty.call(message, 'xTranslate') + ) + writer.uint32(9).double(message.xTranslate); + if ( + message.yTranslate != null && + Object.hasOwnProperty.call(message, 'yTranslate') + ) + writer.uint32(17).double(message.yTranslate); + if ( + message.mTranslate != null && + Object.hasOwnProperty.call(message, 'mTranslate') + ) + writer.uint32(25).double(message.mTranslate); + if ( + message.zTranslate != null && + Object.hasOwnProperty.call(message, 'zTranslate') + ) + writer.uint32(33).double(message.zTranslate); + return writer; + }; + + Translate.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Translate.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.xTranslate != null && message.hasOwnProperty('xTranslate')) + if (typeof message.xTranslate !== 'number') + return 'xTranslate: number expected'; + if (message.yTranslate != null && message.hasOwnProperty('yTranslate')) + if (typeof message.yTranslate !== 'number') + return 'yTranslate: number expected'; + if (message.mTranslate != null && message.hasOwnProperty('mTranslate')) + if (typeof message.mTranslate !== 'number') + return 'mTranslate: number expected'; + if (message.zTranslate != null && message.hasOwnProperty('zTranslate')) + if (typeof message.zTranslate !== 'number') + return 'zTranslate: number expected'; + return null; + }; + + Translate.fromObject = function fromObject(object) { + if ( + object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Translate + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.Translate(); + if (object.xTranslate != null) + message.xTranslate = Number(object.xTranslate); + if (object.yTranslate != null) + message.yTranslate = Number(object.yTranslate); + if (object.mTranslate != null) + message.mTranslate = Number(object.mTranslate); + if (object.zTranslate != null) + message.zTranslate = Number(object.zTranslate); + return message; + }; + + Translate.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.xTranslate = 0; + object.yTranslate = 0; + object.mTranslate = 0; + object.zTranslate = 0; + } + if (message.xTranslate != null && message.hasOwnProperty('xTranslate')) + object.xTranslate = + options.json && !isFinite(message.xTranslate) + ? String(message.xTranslate) + : message.xTranslate; + if (message.yTranslate != null && message.hasOwnProperty('yTranslate')) + object.yTranslate = + options.json && !isFinite(message.yTranslate) + ? String(message.yTranslate) + : message.yTranslate; + if (message.mTranslate != null && message.hasOwnProperty('mTranslate')) + object.mTranslate = + options.json && !isFinite(message.mTranslate) + ? String(message.mTranslate) + : message.mTranslate; + if (message.zTranslate != null && message.hasOwnProperty('zTranslate')) + object.zTranslate = + options.json && !isFinite(message.zTranslate) + ? String(message.zTranslate) + : message.zTranslate; + return object; + }; + + Translate.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Translate.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Translate' + ); + }; + + return Translate; + })(); + + FeatureCollectionPBuffer.Transform = (function () { + function Transform(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + Transform.prototype.quantizeOriginPostion = 0; + Transform.prototype.scale = null; + Transform.prototype.translate = null; + + Transform.create = function create(properties) { + return new Transform(properties); + }; + + Transform.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.quantizeOriginPostion != null && + Object.hasOwnProperty.call(message, 'quantizeOriginPostion') + ) + writer.uint32(8).int32(message.quantizeOriginPostion); + if ( + message.scale != null && + Object.hasOwnProperty.call(message, 'scale') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Scale.encode( + message.scale, + writer.uint32(18).fork(), + ).ldelim(); + if ( + message.translate != null && + Object.hasOwnProperty.call(message, 'translate') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Translate.encode( + message.translate, + writer.uint32(26).fork(), + ).ldelim(); + return writer; + }; + + Transform.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + Transform.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.quantizeOriginPostion != null && + message.hasOwnProperty('quantizeOriginPostion') + ) + switch (message.quantizeOriginPostion) { + default: + return 'quantizeOriginPostion: enum value expected'; + case 0: + case 1: + break; + } + if (message.scale != null && message.hasOwnProperty('scale')) { + var error = $root.esriPBuffer.FeatureCollectionPBuffer.Scale.verify( + message.scale, + ); + if (error) return 'scale.' + error; + } + if (message.translate != null && message.hasOwnProperty('translate')) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Translate.verify( + message.translate, + ); + if (error) return 'translate.' + error; + } + return null; + }; + + Transform.fromObject = function fromObject(object) { + if ( + object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.Transform + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.Transform(); + switch (object.quantizeOriginPostion) { + default: + if (typeof object.quantizeOriginPostion === 'number') { + message.quantizeOriginPostion = object.quantizeOriginPostion; + break; } + break; + case 'upperLeft': + case 0: + message.quantizeOriginPostion = 0; + break; + case 'lowerLeft': + case 1: + message.quantizeOriginPostion = 1; + break; + } + if (object.scale != null) { + if (typeof object.scale !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Transform.scale: object expected', + ); + message.scale = + $root.esriPBuffer.FeatureCollectionPBuffer.Scale.fromObject( + object.scale, + ); + } + if (object.translate != null) { + if (typeof object.translate !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.Transform.translate: object expected', + ); + message.translate = + $root.esriPBuffer.FeatureCollectionPBuffer.Translate.fromObject( + object.translate, + ); + } + return message; + }; + + Transform.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) { + object.quantizeOriginPostion = + options.enums === String ? 'upperLeft' : 0; + object.scale = null; + object.translate = null; + } + if ( + message.quantizeOriginPostion != null && + message.hasOwnProperty('quantizeOriginPostion') + ) + object.quantizeOriginPostion = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer + .QuantizeOriginPostion[message.quantizeOriginPostion] === + undefined + ? message.quantizeOriginPostion + : $root.esriPBuffer.FeatureCollectionPBuffer + .QuantizeOriginPostion[message.quantizeOriginPostion] + : message.quantizeOriginPostion; + if (message.scale != null && message.hasOwnProperty('scale')) + object.scale = + $root.esriPBuffer.FeatureCollectionPBuffer.Scale.toObject( + message.scale, + options, + ); + if (message.translate != null && message.hasOwnProperty('translate')) + object.translate = + $root.esriPBuffer.FeatureCollectionPBuffer.Translate.toObject( + message.translate, + options, + ); + return object; + }; + + Transform.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + Transform.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.Transform' + ); + }; + + return Transform; + })(); - ObjectIdsResult.prototype.objectIdFieldName = ""; - ObjectIdsResult.prototype.serverGens = null; - ObjectIdsResult.prototype.objectIds = $util.emptyArray; - - ObjectIdsResult.create = function create(properties) { - return new ObjectIdsResult(properties); - }; - - ObjectIdsResult.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.objectIdFieldName != null && Object.hasOwnProperty.call(message, "objectIdFieldName")) - writer.uint32(10).string(message.objectIdFieldName); - if (message.serverGens != null && Object.hasOwnProperty.call(message, "serverGens")) - $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.encode(message.serverGens, writer.uint32(18).fork()).ldelim(); - if (message.objectIds != null && message.objectIds.length) { - writer.uint32(26).fork(); - for (var i = 0; i < message.objectIds.length; ++i) - writer.uint64(message.objectIds[i]); - writer.ldelim(); - } - return writer; - }; - - ObjectIdsResult.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - ObjectIdsResult.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - if (message.objectIdFieldName != null && message.hasOwnProperty("objectIdFieldName")) - if (!$util.isString(message.objectIdFieldName)) - return "objectIdFieldName: string expected"; - if (message.serverGens != null && message.hasOwnProperty("serverGens")) { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.verify(message.serverGens); - if (error) - return "serverGens." + error; - } - if (message.objectIds != null && message.hasOwnProperty("objectIds")) { - if (!Array.isArray(message.objectIds)) - return "objectIds: array expected"; - for (var i = 0; i < message.objectIds.length; ++i) - if (!$util.isInteger(message.objectIds[i]) && !(message.objectIds[i] && $util.isInteger(message.objectIds[i].low) && $util.isInteger(message.objectIds[i].high))) - return "objectIds: integer|Long[] expected"; - } - return null; - }; - - ObjectIdsResult.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult(); - if (object.objectIdFieldName != null) - message.objectIdFieldName = String(object.objectIdFieldName); - if (object.serverGens != null) { - if (typeof object.serverGens !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.serverGens: object expected"); - message.serverGens = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.fromObject(object.serverGens); - } - if (object.objectIds) { - if (!Array.isArray(object.objectIds)) - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.objectIds: array expected"); - message.objectIds = []; - for (var i = 0; i < object.objectIds.length; ++i) - if ($util.Long) - (message.objectIds[i] = $util.Long.fromValue(object.objectIds[i])).unsigned = true; - else if (typeof object.objectIds[i] === "string") - message.objectIds[i] = parseInt(object.objectIds[i], 10); - else if (typeof object.objectIds[i] === "number") - message.objectIds[i] = object.objectIds[i]; - else if (typeof object.objectIds[i] === "object") - message.objectIds[i] = new $util.LongBits(object.objectIds[i].low >>> 0, object.objectIds[i].high >>> 0).toNumber(true); - } - return message; - }; - - ObjectIdsResult.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (options.arrays || options.defaults) - object.objectIds = []; - if (options.defaults) { - object.objectIdFieldName = ""; - object.serverGens = null; - } - if (message.objectIdFieldName != null && message.hasOwnProperty("objectIdFieldName")) - object.objectIdFieldName = message.objectIdFieldName; - if (message.serverGens != null && message.hasOwnProperty("serverGens")) - object.serverGens = $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.toObject(message.serverGens, options); - if (message.objectIds && message.objectIds.length) { - object.objectIds = []; - for (var j = 0; j < message.objectIds.length; ++j) - if (typeof message.objectIds[j] === "number") - object.objectIds[j] = options.longs === String ? String(message.objectIds[j]) : message.objectIds[j]; - else - object.objectIds[j] = options.longs === String ? $util.Long.prototype.toString.call(message.objectIds[j]) : options.longs === Number ? new $util.LongBits(message.objectIds[j].low >>> 0, message.objectIds[j].high >>> 0).toNumber(true) : message.objectIds[j]; - } - return object; - }; - - ObjectIdsResult.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - ObjectIdsResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult"; - }; - - return ObjectIdsResult; - })(); - - FeatureCollectionPBuffer.QueryResult = (function() { - - function QueryResult(properties) { - if (properties) - for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) - if (properties[keys[i]] != null) - this[keys[i]] = properties[keys[i]]; + FeatureCollectionPBuffer.FeatureResult = (function () { + function FeatureResult(properties) { + this.fields = []; + this.values = []; + this.features = []; + this.geometryFields = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + FeatureResult.prototype.objectIdFieldName = ''; + FeatureResult.prototype.uniqueIdField = null; + FeatureResult.prototype.globalIdFieldName = ''; + FeatureResult.prototype.geohashFieldName = ''; + FeatureResult.prototype.geometryProperties = null; + FeatureResult.prototype.serverGens = null; + FeatureResult.prototype.geometryType = 0; + FeatureResult.prototype.spatialReference = null; + FeatureResult.prototype.exceededTransferLimit = false; + FeatureResult.prototype.hasZ = false; + FeatureResult.prototype.hasM = false; + FeatureResult.prototype.transform = null; + FeatureResult.prototype.fields = $util.emptyArray; + FeatureResult.prototype.values = $util.emptyArray; + FeatureResult.prototype.features = $util.emptyArray; + FeatureResult.prototype.geometryFields = $util.emptyArray; + + FeatureResult.create = function create(properties) { + return new FeatureResult(properties); + }; + + FeatureResult.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.objectIdFieldName != null && + Object.hasOwnProperty.call(message, 'objectIdFieldName') + ) + writer.uint32(10).string(message.objectIdFieldName); + if ( + message.uniqueIdField != null && + Object.hasOwnProperty.call(message, 'uniqueIdField') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.encode( + message.uniqueIdField, + writer.uint32(18).fork(), + ).ldelim(); + if ( + message.globalIdFieldName != null && + Object.hasOwnProperty.call(message, 'globalIdFieldName') + ) + writer.uint32(26).string(message.globalIdFieldName); + if ( + message.geohashFieldName != null && + Object.hasOwnProperty.call(message, 'geohashFieldName') + ) + writer.uint32(34).string(message.geohashFieldName); + if ( + message.geometryProperties != null && + Object.hasOwnProperty.call(message, 'geometryProperties') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.encode( + message.geometryProperties, + writer.uint32(42).fork(), + ).ldelim(); + if ( + message.serverGens != null && + Object.hasOwnProperty.call(message, 'serverGens') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.encode( + message.serverGens, + writer.uint32(50).fork(), + ).ldelim(); + if ( + message.geometryType != null && + Object.hasOwnProperty.call(message, 'geometryType') + ) + writer.uint32(56).int32(message.geometryType); + if ( + message.spatialReference != null && + Object.hasOwnProperty.call(message, 'spatialReference') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.encode( + message.spatialReference, + writer.uint32(66).fork(), + ).ldelim(); + if ( + message.exceededTransferLimit != null && + Object.hasOwnProperty.call(message, 'exceededTransferLimit') + ) + writer.uint32(72).bool(message.exceededTransferLimit); + if (message.hasZ != null && Object.hasOwnProperty.call(message, 'hasZ')) + writer.uint32(80).bool(message.hasZ); + if (message.hasM != null && Object.hasOwnProperty.call(message, 'hasM')) + writer.uint32(88).bool(message.hasM); + if ( + message.transform != null && + Object.hasOwnProperty.call(message, 'transform') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.Transform.encode( + message.transform, + writer.uint32(98).fork(), + ).ldelim(); + if (message.fields != null && message.fields.length) + for (var i = 0; i < message.fields.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.Field.encode( + message.fields[i], + writer.uint32(106).fork(), + ).ldelim(); + if (message.values != null && message.values.length) + for (var i = 0; i < message.values.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.Value.encode( + message.values[i], + writer.uint32(114).fork(), + ).ldelim(); + if (message.features != null && message.features.length) + for (var i = 0; i < message.features.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.Feature.encode( + message.features[i], + writer.uint32(122).fork(), + ).ldelim(); + if (message.geometryFields != null && message.geometryFields.length) + for (var i = 0; i < message.geometryFields.length; ++i) + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.encode( + message.geometryFields[i], + writer.uint32(130).fork(), + ).ldelim(); + return writer; + }; + + FeatureResult.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + FeatureResult.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.objectIdFieldName != null && + message.hasOwnProperty('objectIdFieldName') + ) + if (!$util.isString(message.objectIdFieldName)) + return 'objectIdFieldName: string expected'; + if ( + message.uniqueIdField != null && + message.hasOwnProperty('uniqueIdField') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.verify( + message.uniqueIdField, + ); + if (error) return 'uniqueIdField.' + error; + } + if ( + message.globalIdFieldName != null && + message.hasOwnProperty('globalIdFieldName') + ) + if (!$util.isString(message.globalIdFieldName)) + return 'globalIdFieldName: string expected'; + if ( + message.geohashFieldName != null && + message.hasOwnProperty('geohashFieldName') + ) + if (!$util.isString(message.geohashFieldName)) + return 'geohashFieldName: string expected'; + if ( + message.geometryProperties != null && + message.hasOwnProperty('geometryProperties') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.verify( + message.geometryProperties, + ); + if (error) return 'geometryProperties.' + error; + } + if ( + message.serverGens != null && + message.hasOwnProperty('serverGens') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.verify( + message.serverGens, + ); + if (error) return 'serverGens.' + error; + } + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + switch (message.geometryType) { + default: + return 'geometryType: enum value expected'; + case 0: + case 1: + case 2: + case 3: + case 4: + case 127: + case 5: + break; + } + if ( + message.spatialReference != null && + message.hasOwnProperty('spatialReference') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.verify( + message.spatialReference, + ); + if (error) return 'spatialReference.' + error; + } + if ( + message.exceededTransferLimit != null && + message.hasOwnProperty('exceededTransferLimit') + ) + if (typeof message.exceededTransferLimit !== 'boolean') + return 'exceededTransferLimit: boolean expected'; + if (message.hasZ != null && message.hasOwnProperty('hasZ')) + if (typeof message.hasZ !== 'boolean') + return 'hasZ: boolean expected'; + if (message.hasM != null && message.hasOwnProperty('hasM')) + if (typeof message.hasM !== 'boolean') + return 'hasM: boolean expected'; + if (message.transform != null && message.hasOwnProperty('transform')) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Transform.verify( + message.transform, + ); + if (error) return 'transform.' + error; + } + if (message.fields != null && message.hasOwnProperty('fields')) { + if (!Array.isArray(message.fields)) return 'fields: array expected'; + for (var i = 0; i < message.fields.length; ++i) { + var error = $root.esriPBuffer.FeatureCollectionPBuffer.Field.verify( + message.fields[i], + ); + if (error) return 'fields.' + error; + } + } + if (message.values != null && message.hasOwnProperty('values')) { + if (!Array.isArray(message.values)) return 'values: array expected'; + for (var i = 0; i < message.values.length; ++i) { + var error = $root.esriPBuffer.FeatureCollectionPBuffer.Value.verify( + message.values[i], + ); + if (error) return 'values.' + error; + } + } + if (message.features != null && message.hasOwnProperty('features')) { + if (!Array.isArray(message.features)) + return 'features: array expected'; + for (var i = 0; i < message.features.length; ++i) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.Feature.verify( + message.features[i], + ); + if (error) return 'features.' + error; + } + } + if ( + message.geometryFields != null && + message.hasOwnProperty('geometryFields') + ) { + if (!Array.isArray(message.geometryFields)) + return 'geometryFields: array expected'; + for (var i = 0; i < message.geometryFields.length; ++i) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.verify( + message.geometryFields[i], + ); + if (error) return 'geometryFields.' + error; + } + } + return null; + }; + + FeatureResult.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult(); + if (object.objectIdFieldName != null) + message.objectIdFieldName = String(object.objectIdFieldName); + if (object.uniqueIdField != null) { + if (typeof object.uniqueIdField !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.uniqueIdField: object expected', + ); + message.uniqueIdField = + $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.fromObject( + object.uniqueIdField, + ); + } + if (object.globalIdFieldName != null) + message.globalIdFieldName = String(object.globalIdFieldName); + if (object.geohashFieldName != null) + message.geohashFieldName = String(object.geohashFieldName); + if (object.geometryProperties != null) { + if (typeof object.geometryProperties !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryProperties: object expected', + ); + message.geometryProperties = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.fromObject( + object.geometryProperties, + ); + } + if (object.serverGens != null) { + if (typeof object.serverGens !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.serverGens: object expected', + ); + message.serverGens = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.fromObject( + object.serverGens, + ); + } + switch (object.geometryType) { + default: + if (typeof object.geometryType === 'number') { + message.geometryType = object.geometryType; + break; } + break; + case 'esriGeometryTypePoint': + case 0: + message.geometryType = 0; + break; + case 'esriGeometryTypeMultipoint': + case 1: + message.geometryType = 1; + break; + case 'esriGeometryTypePolyline': + case 2: + message.geometryType = 2; + break; + case 'esriGeometryTypePolygon': + case 3: + message.geometryType = 3; + break; + case 'esriGeometryTypeMultipatch': + case 4: + message.geometryType = 4; + break; + case 'esriGeometryTypeNone': + case 127: + message.geometryType = 127; + break; + case 'esriGeometryTypeEnvelope': + case 5: + message.geometryType = 5; + break; + } + if (object.spatialReference != null) { + if (typeof object.spatialReference !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.spatialReference: object expected', + ); + message.spatialReference = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.fromObject( + object.spatialReference, + ); + } + if (object.exceededTransferLimit != null) + message.exceededTransferLimit = Boolean(object.exceededTransferLimit); + if (object.hasZ != null) message.hasZ = Boolean(object.hasZ); + if (object.hasM != null) message.hasM = Boolean(object.hasM); + if (object.transform != null) { + if (typeof object.transform !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.transform: object expected', + ); + message.transform = + $root.esriPBuffer.FeatureCollectionPBuffer.Transform.fromObject( + object.transform, + ); + } + if (object.fields) { + if (!Array.isArray(object.fields)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fields: array expected', + ); + message.fields = []; + for (var i = 0; i < object.fields.length; ++i) { + if (typeof object.fields[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fields: object expected', + ); + message.fields[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.Field.fromObject( + object.fields[i], + ); + } + } + if (object.values) { + if (!Array.isArray(object.values)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.values: array expected', + ); + message.values = []; + for (var i = 0; i < object.values.length; ++i) { + if (typeof object.values[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.values: object expected', + ); + message.values[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.Value.fromObject( + object.values[i], + ); + } + } + if (object.features) { + if (!Array.isArray(object.features)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.features: array expected', + ); + message.features = []; + for (var i = 0; i < object.features.length; ++i) { + if (typeof object.features[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.features: object expected', + ); + message.features[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.Feature.fromObject( + object.features[i], + ); + } + } + if (object.geometryFields) { + if (!Array.isArray(object.geometryFields)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryFields: array expected', + ); + message.geometryFields = []; + for (var i = 0; i < object.geometryFields.length; ++i) { + if (typeof object.geometryFields[i] !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.geometryFields: object expected', + ); + message.geometryFields[i] = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.fromObject( + object.geometryFields[i], + ); + } + } + return message; + }; + + FeatureResult.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) { + object.fields = []; + object.values = []; + object.features = []; + object.geometryFields = []; + } + if (options.defaults) { + object.objectIdFieldName = ''; + object.uniqueIdField = null; + object.globalIdFieldName = ''; + object.geohashFieldName = ''; + object.geometryProperties = null; + object.serverGens = null; + object.geometryType = + options.enums === String ? 'esriGeometryTypePoint' : 0; + object.spatialReference = null; + object.exceededTransferLimit = false; + object.hasZ = false; + object.hasM = false; + object.transform = null; + } + if ( + message.objectIdFieldName != null && + message.hasOwnProperty('objectIdFieldName') + ) + object.objectIdFieldName = message.objectIdFieldName; + if ( + message.uniqueIdField != null && + message.hasOwnProperty('uniqueIdField') + ) + object.uniqueIdField = + $root.esriPBuffer.FeatureCollectionPBuffer.UniqueIdField.toObject( + message.uniqueIdField, + options, + ); + if ( + message.globalIdFieldName != null && + message.hasOwnProperty('globalIdFieldName') + ) + object.globalIdFieldName = message.globalIdFieldName; + if ( + message.geohashFieldName != null && + message.hasOwnProperty('geohashFieldName') + ) + object.geohashFieldName = message.geohashFieldName; + if ( + message.geometryProperties != null && + message.hasOwnProperty('geometryProperties') + ) + object.geometryProperties = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryProperties.toObject( + message.geometryProperties, + options, + ); + if (message.serverGens != null && message.hasOwnProperty('serverGens')) + object.serverGens = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.toObject( + message.serverGens, + options, + ); + if ( + message.geometryType != null && + message.hasOwnProperty('geometryType') + ) + object.geometryType = + options.enums === String + ? $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] === undefined + ? message.geometryType + : $root.esriPBuffer.FeatureCollectionPBuffer.GeometryType[ + message.geometryType + ] + : message.geometryType; + if ( + message.spatialReference != null && + message.hasOwnProperty('spatialReference') + ) + object.spatialReference = + $root.esriPBuffer.FeatureCollectionPBuffer.SpatialReference.toObject( + message.spatialReference, + options, + ); + if ( + message.exceededTransferLimit != null && + message.hasOwnProperty('exceededTransferLimit') + ) + object.exceededTransferLimit = message.exceededTransferLimit; + if (message.hasZ != null && message.hasOwnProperty('hasZ')) + object.hasZ = message.hasZ; + if (message.hasM != null && message.hasOwnProperty('hasM')) + object.hasM = message.hasM; + if (message.transform != null && message.hasOwnProperty('transform')) + object.transform = + $root.esriPBuffer.FeatureCollectionPBuffer.Transform.toObject( + message.transform, + options, + ); + if (message.fields && message.fields.length) { + object.fields = []; + for (var j = 0; j < message.fields.length; ++j) + object.fields[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.Field.toObject( + message.fields[j], + options, + ); + } + if (message.values && message.values.length) { + object.values = []; + for (var j = 0; j < message.values.length; ++j) + object.values[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.Value.toObject( + message.values[j], + options, + ); + } + if (message.features && message.features.length) { + object.features = []; + for (var j = 0; j < message.features.length; ++j) + object.features[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.Feature.toObject( + message.features[j], + options, + ); + } + if (message.geometryFields && message.geometryFields.length) { + object.geometryFields = []; + for (var j = 0; j < message.geometryFields.length; ++j) + object.geometryFields[j] = + $root.esriPBuffer.FeatureCollectionPBuffer.GeometryField.toObject( + message.geometryFields[j], + options, + ); + } + return object; + }; + + FeatureResult.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + FeatureResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.FeatureResult' + ); + }; + + return FeatureResult; + })(); + + FeatureCollectionPBuffer.CountResult = (function () { + function CountResult(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + CountResult.prototype.count = $util.Long + ? $util.Long.fromBits(0, 0, true) + : 0; + + CountResult.create = function create(properties) { + return new CountResult(properties); + }; + + CountResult.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.count != null && + Object.hasOwnProperty.call(message, 'count') + ) + writer.uint32(8).uint64(message.count); + return writer; + }; + + CountResult.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + CountResult.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if (message.count != null && message.hasOwnProperty('count')) + if ( + !$util.isInteger(message.count) && + !( + message.count && + $util.isInteger(message.count.low) && + $util.isInteger(message.count.high) + ) + ) + return 'count: integer|Long expected'; + return null; + }; + + CountResult.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.CountResult + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.CountResult(); + if (object.count != null) + if ($util.Long) + (message.count = $util.Long.fromValue(object.count)).unsigned = + true; + else if (typeof object.count === 'string') + message.count = parseInt(object.count, 10); + else if (typeof object.count === 'number') + message.count = object.count; + else if (typeof object.count === 'object') + message.count = new $util.LongBits( + object.count.low >>> 0, + object.count.high >>> 0, + ).toNumber(true); + return message; + }; + + CountResult.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.defaults) + if ($util.Long) { + var long = new $util.Long(0, 0, true); + object.count = + options.longs === String + ? long.toString() + : options.longs === Number + ? long.toNumber() + : long; + } else object.count = options.longs === String ? '0' : 0; + if (message.count != null && message.hasOwnProperty('count')) + if (typeof message.count === 'number') + object.count = + options.longs === String ? String(message.count) : message.count; + else + object.count = + options.longs === String + ? $util.Long.prototype.toString.call(message.count) + : options.longs === Number + ? new $util.LongBits( + message.count.low >>> 0, + message.count.high >>> 0, + ).toNumber(true) + : message.count; + return object; + }; + + CountResult.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + CountResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.CountResult' + ); + }; - QueryResult.prototype.featureResult = null; - QueryResult.prototype.countResult = null; - QueryResult.prototype.idsResult = null; - - var $oneOfFields; - - Object.defineProperty(QueryResult.prototype, "Results", { - get: $util.oneOfGetter($oneOfFields = ["featureResult", "countResult", "idsResult"]), - set: $util.oneOfSetter($oneOfFields) - }); - - QueryResult.create = function create(properties) { - return new QueryResult(properties); - }; - - QueryResult.encode = function encode(message, writer) { - if (!writer) - writer = $Writer.create(); - if (message.featureResult != null && Object.hasOwnProperty.call(message, "featureResult")) - $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.encode(message.featureResult, writer.uint32(10).fork()).ldelim(); - if (message.countResult != null && Object.hasOwnProperty.call(message, "countResult")) - $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.encode(message.countResult, writer.uint32(18).fork()).ldelim(); - if (message.idsResult != null && Object.hasOwnProperty.call(message, "idsResult")) - $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.encode(message.idsResult, writer.uint32(26).fork()).ldelim(); - return writer; - }; - - QueryResult.encodeDelimited = function encodeDelimited(message, writer) { - return this.encode(message, writer).ldelim(); - }; - - QueryResult.verify = function verify(message) { - if (typeof message !== "object" || message === null) - return "object expected"; - var properties = {}; - if (message.featureResult != null && message.hasOwnProperty("featureResult")) { - properties.Results = 1; - { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.verify(message.featureResult); - if (error) - return "featureResult." + error; - } - } - if (message.countResult != null && message.hasOwnProperty("countResult")) { - if (properties.Results === 1) - return "Results: multiple values"; - properties.Results = 1; - { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.verify(message.countResult); - if (error) - return "countResult." + error; - } - } - if (message.idsResult != null && message.hasOwnProperty("idsResult")) { - if (properties.Results === 1) - return "Results: multiple values"; - properties.Results = 1; - { - var error = $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.verify(message.idsResult); - if (error) - return "idsResult." + error; - } - } - return null; - }; - - QueryResult.fromObject = function fromObject(object) { - if (object instanceof $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult) - return object; - var message = new $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult(); - if (object.featureResult != null) { - if (typeof object.featureResult !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.QueryResult.featureResult: object expected"); - message.featureResult = $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fromObject(object.featureResult); - } - if (object.countResult != null) { - if (typeof object.countResult !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.QueryResult.countResult: object expected"); - message.countResult = $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.fromObject(object.countResult); - } - if (object.idsResult != null) { - if (typeof object.idsResult !== "object") - throw TypeError(".esriPBuffer.FeatureCollectionPBuffer.QueryResult.idsResult: object expected"); - message.idsResult = $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.fromObject(object.idsResult); - } - return message; - }; - - QueryResult.toObject = function toObject(message, options) { - if (!options) - options = {}; - var object = {}; - if (message.featureResult != null && message.hasOwnProperty("featureResult")) { - object.featureResult = $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.toObject(message.featureResult, options); - if (options.oneofs) - object.Results = "featureResult"; - } - if (message.countResult != null && message.hasOwnProperty("countResult")) { - object.countResult = $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.toObject(message.countResult, options); - if (options.oneofs) - object.Results = "countResult"; - } - if (message.idsResult != null && message.hasOwnProperty("idsResult")) { - object.idsResult = $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.toObject(message.idsResult, options); - if (options.oneofs) - object.Results = "idsResult"; - } - return object; - }; - - QueryResult.prototype.toJSON = function toJSON() { - return this.constructor.toObject(this, $protobuf.util.toJSONOptions); - }; - - QueryResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { - if (typeUrlPrefix === undefined) { - typeUrlPrefix = "type.googleapis.com"; - } - return typeUrlPrefix + "/esriPBuffer.FeatureCollectionPBuffer.QueryResult"; - }; - - return QueryResult; - })(); - - return FeatureCollectionPBuffer; + return CountResult; })(); - return esriPBuffer; + FeatureCollectionPBuffer.ObjectIdsResult = (function () { + function ObjectIdsResult(properties) { + this.objectIds = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + ObjectIdsResult.prototype.objectIdFieldName = ''; + ObjectIdsResult.prototype.serverGens = null; + ObjectIdsResult.prototype.objectIds = $util.emptyArray; + + ObjectIdsResult.create = function create(properties) { + return new ObjectIdsResult(properties); + }; + + ObjectIdsResult.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.objectIdFieldName != null && + Object.hasOwnProperty.call(message, 'objectIdFieldName') + ) + writer.uint32(10).string(message.objectIdFieldName); + if ( + message.serverGens != null && + Object.hasOwnProperty.call(message, 'serverGens') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.encode( + message.serverGens, + writer.uint32(18).fork(), + ).ldelim(); + if (message.objectIds != null && message.objectIds.length) { + writer.uint32(26).fork(); + for (var i = 0; i < message.objectIds.length; ++i) + writer.uint64(message.objectIds[i]); + writer.ldelim(); + } + return writer; + }; + + ObjectIdsResult.encodeDelimited = function encodeDelimited( + message, + writer, + ) { + return this.encode(message, writer).ldelim(); + }; + + ObjectIdsResult.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + if ( + message.objectIdFieldName != null && + message.hasOwnProperty('objectIdFieldName') + ) + if (!$util.isString(message.objectIdFieldName)) + return 'objectIdFieldName: string expected'; + if ( + message.serverGens != null && + message.hasOwnProperty('serverGens') + ) { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.verify( + message.serverGens, + ); + if (error) return 'serverGens.' + error; + } + if (message.objectIds != null && message.hasOwnProperty('objectIds')) { + if (!Array.isArray(message.objectIds)) + return 'objectIds: array expected'; + for (var i = 0; i < message.objectIds.length; ++i) + if ( + !$util.isInteger(message.objectIds[i]) && + !( + message.objectIds[i] && + $util.isInteger(message.objectIds[i].low) && + $util.isInteger(message.objectIds[i].high) + ) + ) + return 'objectIds: integer|Long[] expected'; + } + return null; + }; + + ObjectIdsResult.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult(); + if (object.objectIdFieldName != null) + message.objectIdFieldName = String(object.objectIdFieldName); + if (object.serverGens != null) { + if (typeof object.serverGens !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.serverGens: object expected', + ); + message.serverGens = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.fromObject( + object.serverGens, + ); + } + if (object.objectIds) { + if (!Array.isArray(object.objectIds)) + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.objectIds: array expected', + ); + message.objectIds = []; + for (var i = 0; i < object.objectIds.length; ++i) + if ($util.Long) + (message.objectIds[i] = $util.Long.fromValue( + object.objectIds[i], + )).unsigned = true; + else if (typeof object.objectIds[i] === 'string') + message.objectIds[i] = parseInt(object.objectIds[i], 10); + else if (typeof object.objectIds[i] === 'number') + message.objectIds[i] = object.objectIds[i]; + else if (typeof object.objectIds[i] === 'object') + message.objectIds[i] = new $util.LongBits( + object.objectIds[i].low >>> 0, + object.objectIds[i].high >>> 0, + ).toNumber(true); + } + return message; + }; + + ObjectIdsResult.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if (options.arrays || options.defaults) object.objectIds = []; + if (options.defaults) { + object.objectIdFieldName = ''; + object.serverGens = null; + } + if ( + message.objectIdFieldName != null && + message.hasOwnProperty('objectIdFieldName') + ) + object.objectIdFieldName = message.objectIdFieldName; + if (message.serverGens != null && message.hasOwnProperty('serverGens')) + object.serverGens = + $root.esriPBuffer.FeatureCollectionPBuffer.ServerGens.toObject( + message.serverGens, + options, + ); + if (message.objectIds && message.objectIds.length) { + object.objectIds = []; + for (var j = 0; j < message.objectIds.length; ++j) + if (typeof message.objectIds[j] === 'number') + object.objectIds[j] = + options.longs === String + ? String(message.objectIds[j]) + : message.objectIds[j]; + else + object.objectIds[j] = + options.longs === String + ? $util.Long.prototype.toString.call(message.objectIds[j]) + : options.longs === Number + ? new $util.LongBits( + message.objectIds[j].low >>> 0, + message.objectIds[j].high >>> 0, + ).toNumber(true) + : message.objectIds[j]; + } + return object; + }; + + ObjectIdsResult.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + ObjectIdsResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + + '/esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult' + ); + }; + + return ObjectIdsResult; + })(); + + FeatureCollectionPBuffer.QueryResult = (function () { + function QueryResult(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + QueryResult.prototype.featureResult = null; + QueryResult.prototype.countResult = null; + QueryResult.prototype.idsResult = null; + + var $oneOfFields; + + Object.defineProperty(QueryResult.prototype, 'Results', { + get: $util.oneOfGetter( + ($oneOfFields = ['featureResult', 'countResult', 'idsResult']), + ), + set: $util.oneOfSetter($oneOfFields), + }); + + QueryResult.create = function create(properties) { + return new QueryResult(properties); + }; + + QueryResult.encode = function encode(message, writer) { + if (!writer) writer = $Writer.create(); + if ( + message.featureResult != null && + Object.hasOwnProperty.call(message, 'featureResult') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.encode( + message.featureResult, + writer.uint32(10).fork(), + ).ldelim(); + if ( + message.countResult != null && + Object.hasOwnProperty.call(message, 'countResult') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.encode( + message.countResult, + writer.uint32(18).fork(), + ).ldelim(); + if ( + message.idsResult != null && + Object.hasOwnProperty.call(message, 'idsResult') + ) + $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.encode( + message.idsResult, + writer.uint32(26).fork(), + ).ldelim(); + return writer; + }; + + QueryResult.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + QueryResult.verify = function verify(message) { + if (typeof message !== 'object' || message === null) + return 'object expected'; + var properties = {}; + if ( + message.featureResult != null && + message.hasOwnProperty('featureResult') + ) { + properties.Results = 1; + { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.verify( + message.featureResult, + ); + if (error) return 'featureResult.' + error; + } + } + if ( + message.countResult != null && + message.hasOwnProperty('countResult') + ) { + if (properties.Results === 1) return 'Results: multiple values'; + properties.Results = 1; + { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.verify( + message.countResult, + ); + if (error) return 'countResult.' + error; + } + } + if (message.idsResult != null && message.hasOwnProperty('idsResult')) { + if (properties.Results === 1) return 'Results: multiple values'; + properties.Results = 1; + { + var error = + $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.verify( + message.idsResult, + ); + if (error) return 'idsResult.' + error; + } + } + return null; + }; + + QueryResult.fromObject = function fromObject(object) { + if ( + object instanceof + $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult + ) + return object; + var message = + new $root.esriPBuffer.FeatureCollectionPBuffer.QueryResult(); + if (object.featureResult != null) { + if (typeof object.featureResult !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.QueryResult.featureResult: object expected', + ); + message.featureResult = + $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.fromObject( + object.featureResult, + ); + } + if (object.countResult != null) { + if (typeof object.countResult !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.QueryResult.countResult: object expected', + ); + message.countResult = + $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.fromObject( + object.countResult, + ); + } + if (object.idsResult != null) { + if (typeof object.idsResult !== 'object') + throw TypeError( + '.esriPBuffer.FeatureCollectionPBuffer.QueryResult.idsResult: object expected', + ); + message.idsResult = + $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.fromObject( + object.idsResult, + ); + } + return message; + }; + + QueryResult.toObject = function toObject(message, options) { + if (!options) options = {}; + var object = {}; + if ( + message.featureResult != null && + message.hasOwnProperty('featureResult') + ) { + object.featureResult = + $root.esriPBuffer.FeatureCollectionPBuffer.FeatureResult.toObject( + message.featureResult, + options, + ); + if (options.oneofs) object.Results = 'featureResult'; + } + if ( + message.countResult != null && + message.hasOwnProperty('countResult') + ) { + object.countResult = + $root.esriPBuffer.FeatureCollectionPBuffer.CountResult.toObject( + message.countResult, + options, + ); + if (options.oneofs) object.Results = 'countResult'; + } + if (message.idsResult != null && message.hasOwnProperty('idsResult')) { + object.idsResult = + $root.esriPBuffer.FeatureCollectionPBuffer.ObjectIdsResult.toObject( + message.idsResult, + options, + ); + if (options.oneofs) object.Results = 'idsResult'; + } + return object; + }; + + QueryResult.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + QueryResult.getTypeUrl = function getTypeUrl(typeUrlPrefix) { + if (typeUrlPrefix === undefined) { + typeUrlPrefix = 'type.googleapis.com'; + } + return ( + typeUrlPrefix + '/esriPBuffer.FeatureCollectionPBuffer.QueryResult' + ); + }; + + return QueryResult; + })(); + + return FeatureCollectionPBuffer; + })(); + + return esriPBuffer; })(); module.exports = $root; diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.js index c0bbd9d3a..18d23f4f5 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.js @@ -9,8 +9,8 @@ function getGeometryTransform(spatialReference, quantizationParameters) { let scale = getSpatialReferenceScaleFactor(spatialReference); return { - scale: {xScale: scale, yScale: scale}, - translate: { xTranslate: 0, yTranslate: 0 } // [-20037700, -30241100], + scale: { xScale: scale, yScale: scale }, + translate: { xTranslate: 0, yTranslate: 0 }, // [-20037700, -30241100], }; } @@ -26,7 +26,7 @@ function getSpatialReferenceScaleFactor({ wkt, wkid }) { if (wktInfo?.UNIT?.name === 'degree') { return 1e-9; } - + if (wktInfo?.UNIT?.convert) { return 1 / wktInfo.UNIT.convert / 10000; } @@ -35,17 +35,16 @@ function getSpatialReferenceScaleFactor({ wkt, wkid }) { } function parseQuantizationParameters(q) { - const { - tolerance = null - } = q; - const scale = tolerance !== null ? q.tolerance: 1; + const { tolerance = null } = q; + const scale = tolerance !== null ? q.tolerance : 1; + + const [xTranslate, yTranslate] = + q.extent != null ? [q.extent.xmin, q.extent.ymax] : [0, 0]; - const [ xTranslate, yTranslate ] = q.extent != null ? [q.extent.xmin, q.extent.ymax] : [0, 0]; - return { originPosition: normalizeOriginPosition(q.originPosition), scale: { xScale: scale, yScale: scale }, - translate: { xTranslate, yTranslate } + translate: { xTranslate, yTranslate }, }; } @@ -62,5 +61,5 @@ function normalizeOriginPosition(originPosition) { } module.exports = { - getGeometryTransform + getGeometryTransform, }; diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.spec.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.spec.js index bf120380f..9441695ae 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/get-geometry-transform.spec.js @@ -17,7 +17,10 @@ describe('getGeometryTransform', () => { spatialReference: { wkid: 102100, latestWkid: 3857 }, }, }; - const result = getGeometryTransform({ wkid: 4326 }, quantizationParameters); + const result = getGeometryTransform( + { wkid: 4326 }, + quantizationParameters, + ); result.should.deepEqual({ originPosition: 'upperLeft', scale: { @@ -45,7 +48,10 @@ describe('getGeometryTransform', () => { spatialReference: { wkid: 102100, latestWkid: 3857 }, }, }; - const result = getGeometryTransform({ wkid: 4326 }, quantizationParameters); + const result = getGeometryTransform( + { wkid: 4326 }, + quantizationParameters, + ); result.should.deepEqual({ originPosition: 'upperLeft', scale: { @@ -73,7 +79,10 @@ describe('getGeometryTransform', () => { spatialReference: { wkid: 102100, latestWkid: 3857 }, }, }; - const result = getGeometryTransform({ wkid: 4326 }, quantizationParameters); + const result = getGeometryTransform( + { wkid: 4326 }, + quantizationParameters, + ); result.should.deepEqual({ originPosition: 'lowerLeft', scale: { @@ -100,7 +109,10 @@ describe('getGeometryTransform', () => { spatialReference: { wkid: 102100, latestWkid: 3857 }, }, }; - const result = getGeometryTransform({ wkid: 4326 }, quantizationParameters); + const result = getGeometryTransform( + { wkid: 4326 }, + quantizationParameters, + ); result.should.deepEqual({ originPosition: 'upperLeft', scale: { @@ -119,7 +131,10 @@ describe('getGeometryTransform', () => { originPosition: 'upperLeft', tolerance: 1.0583354500042335, }; - const result = getGeometryTransform({ wkid: 4326 }, quantizationParameters); + const result = getGeometryTransform( + { wkid: 4326 }, + quantizationParameters, + ); result.should.deepEqual({ originPosition: 'upperLeft', scale: { diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/index.spec.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/index.spec.js index d6c041164..68d84c163 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/index.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/index.spec.js @@ -59,12 +59,18 @@ describe('sendPbf', () => { esri: 'pbf', length: 99, }); - res.set.firstCall.args.should.deepEqual(['content-type', 'application/x-protobuf']); + res.set.firstCall.args.should.deepEqual([ + 'content-type', + 'application/x-protobuf', + ]); res.set.secondCall.args.should.deepEqual(['content-length', 99]); - res.set.thirdCall.args.should.deepEqual(['content-disposition', 'inline;filename=results.pbf']); - + res.set.thirdCall.args.should.deepEqual([ + 'content-disposition', + 'inline;filename=results.pbf', + ]); + res.status.firstCall.args.should.deepEqual([200]); - + transformFeaturesForPbfSpy.firstCall.args.should.deepEqual([ { esri: 'json' }, undefined, @@ -88,12 +94,18 @@ describe('sendPbf', () => { esri: 'pbf', length: 99, }); - res.set.firstCall.args.should.deepEqual(['content-type', 'application/x-protobuf']); + res.set.firstCall.args.should.deepEqual([ + 'content-type', + 'application/x-protobuf', + ]); res.set.secondCall.args.should.deepEqual(['content-length', 99]); - res.set.thirdCall.args.should.deepEqual(['content-disposition', 'inline;filename=results.pbf']); - + res.set.thirdCall.args.should.deepEqual([ + 'content-disposition', + 'inline;filename=results.pbf', + ]); + res.status.firstCall.args.should.deepEqual([200]); - + transformFeaturesForPbfSpy.called.should.equal(false); protoSpy.encode.firstCall.args.should.deepEqual([ @@ -116,12 +128,18 @@ describe('sendPbf', () => { length: 99, }); - res.set.firstCall.args.should.deepEqual(['content-type', 'application/x-protobuf']); + res.set.firstCall.args.should.deepEqual([ + 'content-type', + 'application/x-protobuf', + ]); res.set.secondCall.args.should.deepEqual(['content-length', 99]); - res.set.thirdCall.args.should.deepEqual(['content-disposition', 'inline;filename=results.pbf']); - + res.set.thirdCall.args.should.deepEqual([ + 'content-disposition', + 'inline;filename=results.pbf', + ]); + res.status.firstCall.args.should.deepEqual([200]); - + transformFeaturesForPbfSpy.called.should.equal(false); protoSpy.encode.firstCall.args.should.deepEqual([ diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.js index 82fba08b0..87c95a148 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.js @@ -4,11 +4,20 @@ const { transformToPbfAttributes } = require('./transform-to-pbf-attributes'); const { transformToPbfGeometry } = require('./transform-to-pbf-geometry'); function transformFeaturesForPbf(json, quantizationParameters) { - const { objectIdFieldName, uniqueIdField, geometryType, spatialReference, exceededTransferLimit } = json; + const { + objectIdFieldName, + uniqueIdField, + geometryType, + spatialReference, + exceededTransferLimit, + } = json; const fields = _.orderBy(json.fields, ['name'], ['asc']); - - const geometryTransform = getGeometryTransform(spatialReference, quantizationParameters); - + + const geometryTransform = getGeometryTransform( + spatialReference, + quantizationParameters, + ); + const features = json.features.map( transformFeatureFunction(fields, geometryTransform), ); @@ -17,11 +26,17 @@ function transformFeaturesForPbf(json, quantizationParameters) { objectIdFieldName, uniqueIdField, spatialReference, - fields: fields.map(({name, alias, type}) => ({ name, alias, fieldType: type})), + fields: fields.map(({ name, alias, type }) => ({ + name, + alias, + fieldType: type, + })), features, exceededTransferLimit, transform: geometryTransform, - geometryType: geometryType ? geometryType.replace('esriGeometry', 'esriGeometryType') : 'esriGeometryTypeNone' + geometryType: geometryType + ? geometryType.replace('esriGeometry', 'esriGeometryType') + : 'esriGeometryTypeNone', }; } @@ -36,12 +51,12 @@ function transformFeatureFunction(fields, geometryTransform) { const geometry = transformToPbfGeometry( feature.geometry, - geometryTransform + geometryTransform, ); return { attributes, - geometry + geometry, }; }; } diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.spec.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.spec.js index 61f8f9bff..558ab4b37 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-features-for-pbf.spec.js @@ -90,7 +90,7 @@ const transformedFixture = { }, }, ], - exceededTransferLimit: true + exceededTransferLimit: true, }; describe('transform features for PBF', () => { diff --git a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-to-pbf-geometry.spec.js b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-to-pbf-geometry.spec.js index f2b4fedce..a4a15f5c8 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-to-pbf-geometry.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pbf/transform-to-pbf-geometry.spec.js @@ -1,15 +1,15 @@ -const should = require('should'); // eslint-disable-line +const should = require('should'); const { transformToPbfGeometry } = require('./transform-to-pbf-geometry'); const defaultTransform = { scale: { xScale: 0.0001, - yScale: 0.0001 - },//[0.0001, 0.0001], + yScale: 0.0001, + }, //[0.0001, 0.0001], translate: { xTranslate: -20037700, - yTranslate: -30241100 - } // [-20037700, -30241100], + yTranslate: -30241100, + }, // [-20037700, -30241100], }; describe('transformToPbfGeometry', () => { @@ -51,7 +51,7 @@ describe('transformToPbfGeometry', () => { x: -8571657.3541762847, y: 4704411.394312229, z: 100, - m: 25.3 + m: 25.3, }; const result = transformToPbfGeometry(fixture, defaultTransform); result.should.deepEqual({ @@ -59,7 +59,6 @@ describe('transformToPbfGeometry', () => { coords: [114660426458, -349455113943, 100, 25.3], }); }); - }); describe('line geometry', () => { @@ -78,12 +77,7 @@ describe('transformToPbfGeometry', () => { result.should.deepEqual({ lengths: [3], coords: [ - 64567221232, - -357065421833, - 3339584724, - 0, - 2226389816, - 1534703364, + 64567221232, -357065421833, 3339584724, 0, 2226389816, 1534703364, ], }); }); @@ -102,11 +96,7 @@ describe('transformToPbfGeometry', () => { result.should.deepEqual({ lengths: [3], coords: [ - 65737760897, - -361640524478, - -587036377, - -1064003433, - 464737132, + 65737760897, -361640524478, -587036377, -1064003433, 464737132, -183448868, ], }); @@ -130,16 +120,8 @@ describe('transformToPbfGeometry', () => { result.should.deepEqual({ lengths: [5], coords: [ - 65680416140, - -363479548349, - 0, - 1647807625, - -1113194908, - 0, - 0, - -1647807625, - 1113194908, - 0, + 65680416140, -363479548349, 0, 1647807625, -1113194908, 0, 0, + -1647807625, 1113194908, 0, ], }); }); @@ -180,16 +162,8 @@ describe('transformToPbfGeometry', () => { result.should.deepEqual({ lengths: [3, 2], coords: [ - 62340831416, - -358626214862, - 4452779632, - 0, - 0, - -3205525862, - 62340831416, - -354020794440, - 4452779632, - 0, + 62340831416, -358626214862, 4452779632, 0, 0, -3205525862, + 62340831416, -354020794440, 4452779632, 0, ], }); }); @@ -219,26 +193,9 @@ describe('transformToPbfGeometry', () => { result.should.deepEqual({ lengths: [5, 5], coords: [ - 87944314299, - -346802067873, - 0, - -1403190256, - 2226389816, - 0, - 0, - 1403190256, - -2226389816, - 0, - 92397093931, - -344049811441, - 0, - -1367402279, - 2226389815, - 0, - 0, - 1367402279, - -2226389815, - 0, + 87944314299, -346802067873, 0, -1403190256, 2226389816, 0, 0, + 1403190256, -2226389816, 0, 92397093931, -344049811441, 0, + -1367402279, 2226389815, 0, 0, 1367402279, -2226389815, 0, ], }); }); diff --git a/packages/featureserver/src/response-handlers/helpers/send-pretty-json.js b/packages/featureserver/src/response-handlers/helpers/send-pretty-json.js index ee4c1e0ec..1b4d0a5d3 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pretty-json.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pretty-json.js @@ -1,4 +1,3 @@ - function sendPrettyJson(res, payload) { res.set('Content-Type', 'application/json; charset=utf-8'); res.status(200); @@ -6,5 +5,5 @@ function sendPrettyJson(res, payload) { } module.exports = { - sendPrettyJson + sendPrettyJson, }; diff --git a/packages/featureserver/src/response-handlers/helpers/send-pretty-json.spec.js b/packages/featureserver/src/response-handlers/helpers/send-pretty-json.spec.js index 5ddb67d57..d3f96fec2 100644 --- a/packages/featureserver/src/response-handlers/helpers/send-pretty-json.spec.js +++ b/packages/featureserver/src/response-handlers/helpers/send-pretty-json.spec.js @@ -19,7 +19,9 @@ describe('sendPrettyJson', () => { 'Content-Type', 'application/json; charset=utf-8', ]); - res.send.firstCall.args[0].should.deepEqual(JSON.stringify({ hello: 'world' }, null, 2)); + res.send.firstCall.args[0].should.deepEqual( + JSON.stringify({ hello: 'world' }, null, 2), + ); res.status.firstCall.args[0].should.be.exactly(200); }); }); diff --git a/packages/featureserver/src/response-handlers/index.js b/packages/featureserver/src/response-handlers/index.js index 719c7b057..6049d2c81 100644 --- a/packages/featureserver/src/response-handlers/index.js +++ b/packages/featureserver/src/response-handlers/index.js @@ -1,4 +1,4 @@ module.exports = { queryResponseHandler: require('./query-response-handler'), - generalResponseHandler: require('./general-response-handler') + generalResponseHandler: require('./general-response-handler'), }; diff --git a/packages/featureserver/src/response-handlers/query-response-handler.js b/packages/featureserver/src/response-handlers/query-response-handler.js index 344a67480..6d9966ab5 100644 --- a/packages/featureserver/src/response-handlers/query-response-handler.js +++ b/packages/featureserver/src/response-handlers/query-response-handler.js @@ -1,16 +1,16 @@ -const { - sendCallbackResponse, - sendPrettyJson, - sendPbf -} = require('./helpers'); +const { sendCallbackResponse, sendPrettyJson, sendPbf } = require('./helpers'); -module.exports = function queryResponseHandler (res, payload, requestParameters) { - const {f, callback } = requestParameters; +module.exports = function queryResponseHandler( + res, + payload, + requestParameters, +) { + const { f, callback } = requestParameters; if (typeof callback === 'string') { return sendCallbackResponse(res, payload, callback); } - + if (f === 'pbf') { return sendPbf(res, payload, requestParameters); } @@ -18,6 +18,6 @@ module.exports = function queryResponseHandler (res, payload, requestParameters) if (f === 'pjson') { return sendPrettyJson(res, payload); } - + return res.status(200).json(payload); }; diff --git a/packages/featureserver/src/response-handlers/query-response-handler.spec.js b/packages/featureserver/src/response-handlers/query-response-handler.spec.js index 9b1b1cd66..2ffc6c516 100644 --- a/packages/featureserver/src/response-handlers/query-response-handler.spec.js +++ b/packages/featureserver/src/response-handlers/query-response-handler.spec.js @@ -17,7 +17,7 @@ const responseHandler = proxyquire('./query-response-handler', { './helpers': { sendPrettyJson: sendPrettyJsonSpy, sendCallbackResponse: sendCallbackResponseSpy, - sendPbf: sendPbfSpy + sendPbf: sendPbfSpy, }, }); @@ -77,10 +77,7 @@ describe('query response handler', () => { }, ); - sendPrettyJsonSpy.firstCall.args.should.deepEqual([ - res, - { test: true } - ]); + sendPrettyJsonSpy.firstCall.args.should.deepEqual([res, { test: true }]); }); it('send as pbf', () => { diff --git a/packages/featureserver/src/rest-info-route-handler.js b/packages/featureserver/src/rest-info-route-handler.js index 5c1905baa..b4d422462 100644 --- a/packages/featureserver/src/rest-info-route-handler.js +++ b/packages/featureserver/src/rest-info-route-handler.js @@ -1,18 +1,26 @@ const _ = require('lodash'); const defaults = require('./metadata-defaults'); -function restInfo (data = {}, req) { +function restInfo(data = {}, req) { const versionDefaults = defaults.restInfoDefaults(); - const currentVersion = _.get(req, 'app.locals.config.featureServer.currentVersion', versionDefaults.currentVersion); - const fullVersion = _.get(req, 'app.locals.config.featureServer.fullVersion', versionDefaults.fullVersion); + const currentVersion = _.get( + req, + 'app.locals.config.featureServer.currentVersion', + versionDefaults.currentVersion, + ); + const fullVersion = _.get( + req, + 'app.locals.config.featureServer.fullVersion', + versionDefaults.fullVersion, + ); return { currentVersion, fullVersion, owningSystemUrl: data.owningSystemUrl, authInfo: { - ...data.authInfo - } + ...data.authInfo, + }, }; } diff --git a/packages/featureserver/src/route.js b/packages/featureserver/src/route.js index a739406a7..76870b11d 100644 --- a/packages/featureserver/src/route.js +++ b/packages/featureserver/src/route.js @@ -7,7 +7,10 @@ const generateRenderer = require('./generate-renderer'); const restInfo = require('./rest-info-route-handler'); const serverInfo = require('./server-info-route-handler'); const layersInfo = require('./layers-metadata'); -const { generalResponseHandler, queryResponseHandler } = require('./response-handlers'); +const { + generalResponseHandler, + queryResponseHandler, +} = require('./response-handlers'); const { validateInputs, normalizeRequestParameters } = require('./helpers'); module.exports = function route(req, res, geojson = {}) { @@ -31,34 +34,37 @@ module.exports = function route(req, res, geojson = {}) { req = { ...req, query: params }; geojson.metadata = geojson.metadata || { maxRecordCount: 2000 }; - + if (isRestInfoRequest(route)) { const result = restInfo(geojson, req); return generalResponseHandler(res, result, req.query); } - + if (isServerMetadataRequest(route)) { const result = serverInfo(geojson, req); return generalResponseHandler(res, result, req.query); - } - - if (isLayersMetadataRequest(route) || isRelationshipsMetadataRequest(route)) { + } + + if ( + isLayersMetadataRequest(route) || + isRelationshipsMetadataRequest(route) + ) { const result = layersInfo(geojson, params); return generalResponseHandler(res, result, req.query); } - + if (isLayerMetadataRequest(method, route)) { const result = layerInfo(geojson, req); return generalResponseHandler(res, result, req.query); } - + if (method) { const operationResult = handleMethodRequest({ method, geojson, req }); if (method === 'query') { return queryResponseHandler(res, operationResult, req.query); } - + return generalResponseHandler(res, operationResult, req.query); } @@ -67,12 +73,16 @@ module.exports = function route(req, res, geojson = {}) { throw error; } catch (error) { logManager.logger.debug(error); - const { code = 500 , message, details = [message] } = error; - + const { code = 500, message, details = [message] } = error; + // Geoservice spec wraps all errors in a 200 response (!) - return generalResponseHandler(res, { - error: { code, message, details } - }, req.query ); + return generalResponseHandler( + res, + { + error: { code, message, details }, + }, + req.query, + ); } }; @@ -94,7 +104,6 @@ function handleMethodRequest({ method, geojson, req }) { throw error; } - function isRestInfoRequest(url) { return /\/rest\/info$/i.test(url); } diff --git a/packages/featureserver/src/server-info-route-handler.js b/packages/featureserver/src/server-info-route-handler.js index dbe2bacb9..51277d713 100644 --- a/packages/featureserver/src/server-info-route-handler.js +++ b/packages/featureserver/src/server-info-route-handler.js @@ -86,9 +86,11 @@ function calculateServiceExtentFromLayers(layers, spatialReference) { }) .map((layer) => { const bounds = calculateBounds(layer); - bounds.forEach(coordinate => { + bounds.forEach((coordinate) => { if (isNaN(coordinate)) { - throw new Error(`Geometry coordinate is not a number: ${coordinate}`); + throw new Error( + `Geometry coordinate is not a number: ${coordinate}`, + ); } }); return bounds; @@ -113,7 +115,9 @@ function calculateServiceExtentFromLayers(layers, spatialReference) { spatialReference, }; } catch (error) { - logManager.logger.debug(`Could not calculate extent from data: ${error.message}`); + logManager.logger.debug( + `Could not calculate extent from data: ${error.message}`, + ); } } @@ -130,7 +134,7 @@ function getExtent(extent, spatialReference) { try { return normalizeExtent(extent, spatialReference); } catch (error) { - logManager.logger.warn(`Could not normalize extent: ${ error }`); + logManager.logger.warn(`Could not normalize extent: ${error}`); } } diff --git a/packages/featureserver/src/server-info-route-handler.spec.js b/packages/featureserver/src/server-info-route-handler.spec.js index 849f2d8a6..466eb3dd8 100644 --- a/packages/featureserver/src/server-info-route-handler.spec.js +++ b/packages/featureserver/src/server-info-route-handler.spec.js @@ -36,9 +36,15 @@ describe('server info', () => { ]); }); - it('should construct options from empty geojson and app config', () => { - const serverInfo = serverInfoHandler({}, { app: { locals: { config: { featureServer: { currentVersion: 101.1 } } } }}); + const serverInfo = serverInfoHandler( + {}, + { + app: { + locals: { config: { featureServer: { currentVersion: 101.1 } } }, + }, + }, + ); serverInfo.should.deepEqual({ server: 'metadata' }); @@ -75,7 +81,7 @@ describe('server info', () => { subLayerIds: null, minScale: 0, maxScale: 0, - type: 'Table' + type: 'Table', }, ], relationships: [], @@ -114,7 +120,7 @@ describe('server info', () => { subLayerIds: null, minScale: 0, maxScale: 0, - type: 'Table' + type: 'Table', }, ], relationships: [], @@ -185,7 +191,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, ], tables: [], @@ -309,7 +315,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, { id: 1, @@ -320,7 +326,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, ], tables: [ @@ -332,7 +338,7 @@ describe('server info', () => { subLayerIds: null, minScale: 0, maxScale: 0, - type: 'Table' + type: 'Table', }, ], fullExtent: { @@ -410,10 +416,7 @@ describe('server info', () => { ], }, ]; - const relationships = [ - { id: 0, name: 'Relationship_0' }, - { id: 1 }, - ]; + const relationships = [{ id: 0, name: 'Relationship_0' }, { id: 1 }]; const input = { maxRecordCount: 5000, hasStaticData: true, @@ -467,7 +470,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, { id: 1, @@ -478,7 +481,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, ], tables: [ @@ -490,7 +493,7 @@ describe('server info', () => { subLayerIds: null, minScale: 0, maxScale: 0, - type: 'Table' + type: 'Table', }, ], fullExtent: { @@ -555,7 +558,7 @@ describe('server info', () => { minScale: 0, maxScale: 0, geometryType: 'esriGeometryPoint', - type: 'Feature Layer' + type: 'Feature Layer', }, ], tables: [], diff --git a/packages/featureserver/test/integration/query.spec.js b/packages/featureserver/test/integration/query.spec.js index 5778c3c97..73240553c 100644 --- a/packages/featureserver/test/integration/query.spec.js +++ b/packages/featureserver/test/integration/query.spec.js @@ -22,17 +22,23 @@ describe('Query operations', () => { // The existing hard-coded OBJECTID's were generated by a unix-based farmhash, and would cause // the tests to fail when run on windows. const response = FeatureServer.query(data, { outFields: 'OBJECTID' }); - this.objectIds = response.features.map(feat => feat.attributes.OBJECTID); - const textOIDResponse = FeatureServer.query(dataWithTextOID, { outFields: 'OBJECTID' }); - this.textObjectIds = textOIDResponse.features.map(feat => feat.attributes.OBJECTID); + this.objectIds = response.features.map((feat) => feat.attributes.OBJECTID); + const textOIDResponse = FeatureServer.query(dataWithTextOID, { + outFields: 'OBJECTID', + }); + this.textObjectIds = textOIDResponse.features.map( + (feat) => feat.attributes.OBJECTID, + ); }); it('should return the expected response schema for an optionless query', () => { const response = FeatureServer.query(data, {}); const featuresSchemaOverride = featuresTemplateSchema.append({ - geometryType: 'esriGeometryPoint' + geometryType: 'esriGeometryPoint', }); - featuresSchemaOverride.validate(response, { presence: 'required' }).should.not.have.property('error'); + featuresSchemaOverride + .validate(response, { presence: 'required' }) + .should.not.have.property('error'); }); it('should return only requested "outFields" set in options', () => { @@ -74,7 +80,10 @@ describe('Query operations', () => { describe('non-WGS84 input dataset', function () { it('should translate the data properly when geojson.crs is defined', function () { - const response = FeatureServer.query(taggedNonWGS84, { limit: 1, returnGeometry: true }); + const response = FeatureServer.query(taggedNonWGS84, { + limit: 1, + returnGeometry: true, + }); response.geometryType.should.equal('esriGeometryPoint'); response.features.length.should.equal(1); response.features[0].attributes.OBJECTID.should.equal(31724); @@ -87,7 +96,10 @@ describe('Query operations', () => { it('should translate the data properly req.inputCrs is defined', function () { const data = _.cloneDeep(untaggedNonWGS84); data.metadata = { crs: 102645 }; - const response = FeatureServer.query(untaggedNonWGS84, { limit: 1, returnGeometry: true }); + const response = FeatureServer.query(untaggedNonWGS84, { + limit: 1, + returnGeometry: true, + }); response.features.length.should.equal(1); response.features[0].attributes.OBJECTID.should.equal(31724); response.features[0].geometry.x.should.equal(6514038.953486104); @@ -97,7 +109,11 @@ describe('Query operations', () => { }); it('should translate the data properly req.inputCrs is defined', function () { - const response = FeatureServer.query(untaggedNonWGS84, { inputCrs: 102645, limit: 1, returnGeometry: true }); + const response = FeatureServer.query(untaggedNonWGS84, { + inputCrs: 102645, + limit: 1, + returnGeometry: true, + }); response.features.length.should.equal(1); response.features[0].attributes.OBJECTID.should.equal(31724); response.features[0].geometry.x.should.equal(6514038.953486104); @@ -109,7 +125,11 @@ describe('Query operations', () => { describe('when using an outSR', function () { it('should translate the data properly', function () { - const response = FeatureServer.query(data, { outSR: { latestWkid: 102100 }, limit: 1, returnGeometry: true }); + const response = FeatureServer.query(data, { + outSR: { latestWkid: 102100 }, + limit: 1, + returnGeometry: true, + }); response.geometryType.should.equal('esriGeometryPoint'); response.features.length.should.equal(1); response.features[0].attributes.OBJECTID.should.equal(this.objectIds[0]); @@ -120,7 +140,11 @@ describe('Query operations', () => { }); it('should translate the data properly when outSR is just a number', function () { - const response = FeatureServer.query(data, { outSR: 102100, limit: 1, returnGeometry: true }); + const response = FeatureServer.query(data, { + outSR: 102100, + limit: 1, + returnGeometry: true, + }); response.features.length.should.equal(1); response.features[0].geometry.x.should.equal(-11682713.391976157); response.features[0].geometry.y.should.equal(4857924.005275469); @@ -131,21 +155,27 @@ describe('Query operations', () => { // move to monorepo e2e tests describe.skip('when getting featureserver features by id queries', function () { it('should return a proper features', function () { - const response = FeatureServer.query(data, { objectIds: this.objectIds.slice(0, 3).join(',') }); + const response = FeatureServer.query(data, { + objectIds: this.objectIds.slice(0, 3).join(','), + }); response.should.be.an.instanceOf(Object); response.fields.should.be.an.instanceOf(Array); response.features.should.have.length(3); }); it('should work with single id', function () { - const response = FeatureServer.query(data, { objectIds: this.objectIds[0] }); + const response = FeatureServer.query(data, { + objectIds: this.objectIds[0], + }); response.should.be.an.instanceOf(Object); response.fields.should.be.an.instanceOf(Array); response.features.should.have.length(1); }); it('should work with string id features', function () { - const response = FeatureServer.query(dataWithTextOID, { objectIds: this.textObjectIds.slice(0, 2).join(',') }); + const response = FeatureServer.query(dataWithTextOID, { + objectIds: this.textObjectIds.slice(0, 2).join(','), + }); response.should.be.an.instanceOf(Object); response.fields.should.be.an.instanceOf(Array); response.features.should.have.length(2); @@ -154,7 +184,7 @@ describe('Query operations', () => { it('should return only count of features', function () { const response = FeatureServer.query(data, { returnCountOnly: true, - objectIds: this.objectIds.slice(0, 3).join(',') + objectIds: this.objectIds.slice(0, 3).join(','), }); response.should.be.an.instanceOf(Object); response.should.have.property('count'); @@ -163,7 +193,7 @@ describe('Query operations', () => { it('should work with a single OID', () => { const response = FeatureServer.query(fullySpecified, { - objectIds: 1 + objectIds: 1, }); response.features.length.should.equal(1); }); @@ -172,7 +202,7 @@ describe('Query operations', () => { describe('when getting features with returnIdsOnly', function () { it('should return only ids of features', function () { const response = FeatureServer.query(data, { - returnIdsOnly: true + returnIdsOnly: true, }); response.should.be.an.instanceOf(Object); response.should.have.property('objectIdFieldName', 'OBJECTID'); @@ -184,7 +214,7 @@ describe('Query operations', () => { it('should return geometries that are contained', () => { const response = FeatureServer.query(data, { geometry: { xmin: -110, ymin: 30, xmax: -106, ymax: 50 }, - geometryType: 'esriGeometryEnvelope' + geometryType: 'esriGeometryEnvelope', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(100); @@ -194,8 +224,14 @@ describe('Query operations', () => { describe('when filtering features with a geometry and outSR', function () { it('should return geometries that are contained', () => { const response = FeatureServer.query(data, { - geometry: { xmin: -110, ymin: 30, xmax: -106, ymax: 50, spatialReference: { wkid: 4326 } }, - geometryType: 'esriGeometryEnvelope' + geometry: { + xmin: -110, + ymin: 30, + xmax: -106, + ymax: 50, + spatialReference: { wkid: 4326 }, + }, + geometryType: 'esriGeometryEnvelope', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(100); @@ -204,8 +240,14 @@ describe('Query operations', () => { it('should still have the correct outSR even when projection is already applied', () => { const response = FeatureServer.query(projectionApplied, { outSR: 102100, - geometry: { xmin: -110, ymin: 30, xmax: -106, ymax: 50, spatialReference: { wkid: 4326 } }, - geometryType: 'esriGeometryEnvelope' + geometry: { + xmin: -110, + ymin: 30, + xmax: -106, + ymax: 50, + spatialReference: { wkid: 4326 }, + }, + geometryType: 'esriGeometryEnvelope', }); response.spatialReference.wkid.should.equal(102100); response.should.be.an.instanceOf(Object); @@ -216,9 +258,15 @@ describe('Query operations', () => { describe('when filtering features with a geometry and outSR', function () { it('should return geometries that are contained', () => { const response = FeatureServer.query(data, { - geometry: { xmin: -110, ymin: 30, xmax: -106, ymax: 50, spatialReference: { wkid: 4326 } }, + geometry: { + xmin: -110, + ymin: 30, + xmax: -106, + ymax: 50, + spatialReference: { wkid: 4326 }, + }, geometryType: 'esriGeometryEnvelope', - spatialRel: 'esriSpatialRelContains' + spatialRel: 'esriSpatialRelContains', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(100); @@ -228,9 +276,15 @@ describe('Query operations', () => { describe('when filtering polygon features with a geometry', function () { it('should return geometries that are contained by given bounds', () => { const response = FeatureServer.query(polyData, { - geometry: { xmin: -180, ymin: -90, xmax: 180, ymax: 90, spatialReference: { wkid: 4326 } }, + geometry: { + xmin: -180, + ymin: -90, + xmax: 180, + ymax: 90, + spatialReference: { wkid: 4326 }, + }, geometryType: 'esriGeometryEnvelope', - spatialRel: 'esriSpatialRelContains' + spatialRel: 'esriSpatialRelContains', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(1); @@ -240,7 +294,7 @@ describe('Query operations', () => { describe('when filtering features with where clauses', function () { it('should return filtered features with less than', () => { const response = FeatureServer.query(data, { - where: 'latitude < 39.9137' + where: 'latitude < 39.9137', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(261); @@ -248,7 +302,7 @@ describe('Query operations', () => { it('should return filtered features with greater than', () => { const response = FeatureServer.query(data, { - where: 'latitude > 39.9137' + where: 'latitude > 39.9137', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(144); @@ -256,7 +310,7 @@ describe('Query operations', () => { it('should return filtered features with equal', () => { const response = FeatureServer.query(data, { - where: 'latitude = 39.9137' + where: 'latitude = 39.9137', }); response.should.be.an.instanceOf(Object); response.features.length.should.equal(1); @@ -269,7 +323,7 @@ describe('Query operations', () => { returnGeometry: false, resultOffset: 0, resultRecordCount: 10, - outFields: '*' + outFields: '*', }; const response = FeatureServer.query(budgetTable, options); @@ -285,7 +339,7 @@ describe('Query operations', () => { returnGeometry: false, resultOffset: 0, resultRecordCount: 10, - outFields: 'OBJECTID,Name,Dept' + outFields: 'OBJECTID,Name,Dept', }; const response = FeatureServer.query(budgetTable, options); @@ -303,13 +357,17 @@ describe('Query operations', () => { f: 'json', returnGeometry: false, resultRecordCount: 1, - outFields: 'Name,Dept' + outFields: 'Name,Dept', }; const response = FeatureServer.query(budgetTable, options); response.fields.length.should.equal(2); - response.fields.find(field => field.name === 'Name').name.should.equal('Name'); - response.fields.find(field => field.name === 'Dept').name.should.equal('Dept'); + response.fields + .find((field) => field.name === 'Name') + .name.should.equal('Name'); + response.fields + .find((field) => field.name === 'Dept') + .name.should.equal('Dept'); Object.keys(response.features[0].attributes).length.should.equal(2); _.has(response, 'features[0].attributes.OBJECTID').should.equal(false); }); @@ -318,31 +376,37 @@ describe('Query operations', () => { describe('querying for statistics', function () { describe('results are passed in', function () { it('should properly render a group-by response', function () { - const response = FeatureServer.query({ - statistics: [ - { - FACUSE: 'Middle School', - TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 - }, - { - FACUSE: 'Elementary School', - TOTAL_STUD_SUM: 23802, - ZIP_CODE_COUNT: 72 - } - ] - }, { - groupByFieldsForStatistics: 'FACUSE', - outStatistics: [{ - statisticType: 'sum', - onStatisticField: 'Student Count', - outStatisticFieldName: 'TOTAL_STUD_SUM' - }, { - statisticType: 'count', - onStatisticField: 'ZIP_CODE', - outStatisticFieldName: 'ZIP_CODE_COUNT' - }] - }); + const response = FeatureServer.query( + { + statistics: [ + { + FACUSE: 'Middle School', + TOTAL_STUD_SUM: 5421, + ZIP_CODE_COUNT: 18, + }, + { + FACUSE: 'Elementary School', + TOTAL_STUD_SUM: 23802, + ZIP_CODE_COUNT: 72, + }, + ], + }, + { + groupByFieldsForStatistics: 'FACUSE', + outStatistics: [ + { + statisticType: 'sum', + onStatisticField: 'Student Count', + outStatisticFieldName: 'TOTAL_STUD_SUM', + }, + { + statisticType: 'count', + onStatisticField: 'ZIP_CODE', + outStatisticFieldName: 'ZIP_CODE_COUNT', + }, + ], + }, + ); response.should.deepEqual({ fields: [ { @@ -352,7 +416,7 @@ describe('Query operations', () => { defaultValue: null, domain: null, sqlType: 'sqlTypeOther', - length: 128 + length: 128, }, { name: 'TOTAL_STUD_SUM', @@ -360,7 +424,7 @@ describe('Query operations', () => { alias: 'TOTAL_STUD_SUM', defaultValue: null, domain: null, - sqlType: 'sqlTypeFloat' + sqlType: 'sqlTypeFloat', }, { name: 'ZIP_CODE_COUNT', @@ -368,25 +432,25 @@ describe('Query operations', () => { alias: 'ZIP_CODE_COUNT', defaultValue: null, domain: null, - sqlType: 'sqlTypeFloat' - } + sqlType: 'sqlTypeFloat', + }, ], features: [ { attributes: { FACUSE: 'Middle School', TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 - } + ZIP_CODE_COUNT: 18, + }, }, { attributes: { FACUSE: 'Elementary School', TOTAL_STUD_SUM: 23802, - ZIP_CODE_COUNT: 72 - } - } - ] + ZIP_CODE_COUNT: 72, + }, + }, + ], }); }); @@ -394,8 +458,8 @@ describe('Query operations', () => { const response = FeatureServer.query({ statistics: { TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 - } + ZIP_CODE_COUNT: 18, + }, }); response.should.deepEqual({ fields: [ @@ -405,7 +469,7 @@ describe('Query operations', () => { alias: 'TOTAL_STUD_SUM', domain: null, defaultValue: null, - sqlType: 'sqlTypeFloat' + sqlType: 'sqlTypeFloat', }, { name: 'ZIP_CODE_COUNT', @@ -413,17 +477,17 @@ describe('Query operations', () => { alias: 'ZIP_CODE_COUNT', domain: null, defaultValue: null, - sqlType: 'sqlTypeFloat' - } + sqlType: 'sqlTypeFloat', + }, ], features: [ { attributes: { TOTAL_STUD_SUM: 5421, - ZIP_CODE_COUNT: 18 - } - } - ] + ZIP_CODE_COUNT: 18, + }, + }, + ], }); }); @@ -432,17 +496,17 @@ describe('Query operations', () => { type: 'FeatureCollection', statistics: [ { - dateField: '2017-06-16T01:58:36.179Z' - } + dateField: '2017-06-16T01:58:36.179Z', + }, ], metadata: { fields: [ { name: 'dateField', - type: 'Date' - } - ] - } + type: 'Date', + }, + ], + }, }); response.features[0].attributes.dateField.should.equal(1497578316179); response.fields[0].type.should.equal('esriFieldTypeDate'); @@ -453,68 +517,76 @@ describe('Query operations', () => { type: 'FeatureCollection', statistics: [ { - dateField: '2017-06-16T01:58:36.179Z' - } - ] + dateField: '2017-06-16T01:58:36.179Z', + }, + ], }); response.features[0].attributes.dateField.should.equal(1497578316179); response.fields[0].type.should.equal('esriFieldTypeDate'); }); it('should respect metadata when date field is passed in', () => { - const response = FeatureServer.query({ - type: 'FeatureCollection', - statistics: [ - { - dateField: 1497578316179 - } - ], - metadata: { - fields: [ + const response = FeatureServer.query( + { + type: 'FeatureCollection', + statistics: [ { - name: 'dateField', - type: 'Date' - } - ] - } - }, { - outStatistics: [ - { - statisticType: 'MIN', - onStatisticField: 'dateField' - } - ] - }); + dateField: 1497578316179, + }, + ], + metadata: { + fields: [ + { + name: 'dateField', + type: 'Date', + }, + ], + }, + }, + { + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'dateField', + }, + ], + }, + ); response.features[0].attributes.dateField.should.equal(1497578316179); response.fields[0].type.should.equal('esriFieldTypeDate'); }); it('should respect metadata when date field is passed in and custom stat label', () => { - const response = FeatureServer.query({ - type: 'FeatureCollection', - statistics: [ - { - some_new_label: 1497578316179 - } - ], - metadata: { - fields: [ + const response = FeatureServer.query( + { + type: 'FeatureCollection', + statistics: [ { - name: 'dateField', - type: 'Date' - } - ] - } - }, { - outStatistics: [ - { - statisticType: 'MIN', - onStatisticField: 'dateField', - outStatisticFieldName: 'some_new_label' - } - ] - }); - response.features[0].attributes.some_new_label.should.equal(1497578316179); + some_new_label: 1497578316179, + }, + ], + metadata: { + fields: [ + { + name: 'dateField', + type: 'Date', + }, + ], + }, + }, + { + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'dateField', + outStatisticFieldName: 'some_new_label', + }, + ], + }, + ); + response.features[0].attributes.some_new_label.should.equal( + 1497578316179, + ); response.fields[0].type.should.equal('esriFieldTypeDate'); }); }); @@ -522,11 +594,13 @@ describe('Query operations', () => { describe('calculating from geojson', function () { it('should return correct fields and features for one stat', () => { const response = FeatureServer.query(data, { - outStatistics: [{ - statisticType: 'MIN', - onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' - }] + outStatistics: [ + { + statisticType: 'MIN', + onStatisticField: 'total precip', + outStatisticFieldName: 'min_precip', + }, + ], }); response.should.be.an.instanceOf(Object); response.fields.length.should.equal(1); @@ -540,14 +614,14 @@ describe('Query operations', () => { { statisticType: 'min', onStatisticField: 'total precip', - outStatisticFieldName: 'min_precip' + outStatisticFieldName: 'min_precip', }, { statisticType: 'max', onStatisticField: 'total precip', - outStatisticFieldName: 'max_precip' - } - ] + outStatisticFieldName: 'max_precip', + }, + ], }); response.should.be.an.instanceOf(Object); response.fields.length.should.equal(2); @@ -562,9 +636,9 @@ describe('Query operations', () => { { statisticType: 'count', onStatisticField: 'total precip', - outStatisticFieldName: 'count_precip' - } - ] + outStatisticFieldName: 'count_precip', + }, + ], }); response.should.be.an.instanceOf(Object); response.fields.length.should.equal(1); @@ -574,38 +648,58 @@ describe('Query operations', () => { it('should return correct number of fields and features for sum stats', () => { const response = FeatureServer.query(data, { - outStatistics: [{ - statisticType: 'sum', - onStatisticField: 'total precip', - outStatisticFieldName: 'sum_precip' - }] + outStatistics: [ + { + statisticType: 'sum', + onStatisticField: 'total precip', + outStatisticFieldName: 'sum_precip', + }, + ], }); response.should.be.an.instanceOf(Object); response.fields.length.should.equal(1); response.features.length.should.equal(1); - response.features[0].attributes.sum_precip.should.equal(135.69000000000003); + response.features[0].attributes.sum_precip.should.equal( + 135.69000000000003, + ); }); it('should return correct number of fields and features for avg stats', () => { const response = FeatureServer.query(data, { - outStatistics: [{ - statisticType: 'avg', - onStatisticField: 'total precip', - outStatisticFieldName: 'avg_precip' - }] + outStatistics: [ + { + statisticType: 'avg', + onStatisticField: 'total precip', + outStatisticFieldName: 'avg_precip', + }, + ], }); - response.features[0].attributes.avg_precip.should.equal(0.3253956834532375); + response.features[0].attributes.avg_precip.should.equal( + 0.3253956834532375, + ); }); it.skip('should return correct number of fields and features for var/stddev stats', () => { const response = FeatureServer.query(data, { outStatistics: [ - { statisticType: 'var', onStatisticField: 'total precip', outStatisticFieldName: 'var_precip' }, - { statisticType: 'stddev', onStatisticField: 'total precip', outStatisticFieldName: 'stddev_precip' } - ] + { + statisticType: 'var', + onStatisticField: 'total precip', + outStatisticFieldName: 'var_precip', + }, + { + statisticType: 'stddev', + onStatisticField: 'total precip', + outStatisticFieldName: 'stddev_precip', + }, + ], }); - response.features[0].attributes.var_precip.should.equal(0.07661480700055341); - response.features[0].attributes.stddev_precip.should.equal(0.27646171244241985); + response.features[0].attributes.var_precip.should.equal( + 0.07661480700055341, + ); + response.features[0].attributes.stddev_precip.should.equal( + 0.27646171244241985, + ); }); it('should return a correct response when there are multiple stats returned', () => { @@ -619,25 +713,38 @@ describe('Query operations', () => { sqlFormat: 'standard', f: 'json', groupByFieldsForStatistics: 'Full/Part', - outStatistics: [{ - statisticType: 'count', - onStatisticField: 'Full/Part', - outStatisticFieldName: 'Full/Part_COUNT' - }], - orderByFields: 'Full/Part_COUNT DESC' + outStatistics: [ + { + statisticType: 'count', + onStatisticField: 'Full/Part', + outStatisticFieldName: 'Full/Part_COUNT', + }, + ], + orderByFields: 'Full/Part_COUNT DESC', }; const response = FeatureServer.query(budgetTable, options); response.features[0].attributes['Full/Part_COUNT'].should.equal(6644); - response.fields.findIndex(f => { return f.name === 'Full/Part_COUNT'; }).should.not.equal(-1); - response.fields.findIndex(f => { return f.name === 'Full/Part'; }).should.not.equal(-1); + response.fields + .findIndex((f) => { + return f.name === 'Full/Part_COUNT'; + }) + .should.not.equal(-1); + response.fields + .findIndex((f) => { + return f.name === 'Full/Part'; + }) + .should.not.equal(-1); }); }); }); describe('when getting feature counts from a given count', () => { it('should return a correct count json', () => { - const json = FeatureServer.query({ count: 100 }, { returnCountOnly: true }); + const json = FeatureServer.query( + { count: 100 }, + { returnCountOnly: true }, + ); json.count.should.equal(100); }); }); @@ -645,7 +752,7 @@ describe('Query operations', () => { describe('query that results in 0 features', () => { it('should still return fields', () => { const json = FeatureServer.query(data, { - where: '"total precip" > 10000' + where: '"total precip" > 10000', }); json.fields.length.should.equal(10); json.features.length.should.equal(0); @@ -656,7 +763,7 @@ describe('Query operations', () => { it('should respect f=geojson when querying for features', () => { const json = FeatureServer.query(data, { where: '"total precip" > 1', - f: 'geojson' + f: 'geojson', }); json.type.should.equal('FeatureCollection'); json.features.length.should.equal(4); @@ -682,7 +789,10 @@ describe('Query operations', () => { describe('when an offset has already been applied', () => { it('should remove the result offset', () => { - const json = FeatureServer.query(offsetApplied, { resultOffset: 50, resultRecordCount: 1 }); + const json = FeatureServer.query(offsetApplied, { + resultOffset: 50, + resultRecordCount: 1, + }); json.features.length.should.be.greaterThan(0); }); }); @@ -694,7 +804,10 @@ describe('Query operations', () => { }); it('should pass through a count of 1', () => { - const json = FeatureServer.query({ count: 1, features: [{}] }, { returnCountOnly: true }); + const json = FeatureServer.query( + { count: 1, features: [{}] }, + { returnCountOnly: true }, + ); json.count.should.equal(1); }); }); @@ -714,7 +827,10 @@ describe('Query operations', () => { }); it('should return extent of features and count of features', () => { - const response = FeatureServer.query(data, { returnExtentOnly: true, returnCountOnly: true }); + const response = FeatureServer.query(data, { + returnExtentOnly: true, + returnCountOnly: true, + }); response.should.be.an.instanceOf(Object); response.should.have.property('count', 417); response.should.have.property('extent'); @@ -727,7 +843,10 @@ describe('Query operations', () => { }); it('should return extent of features in specified outSR', () => { - const response = FeatureServer.query(data, { returnExtentOnly: true, outSR: 3857 }); + const response = FeatureServer.query(data, { + returnExtentOnly: true, + outSR: 3857, + }); response.should.be.an.instanceOf(Object); response.should.have.property('extent'); response.extent.should.have.property('xmin', -12127089.667273825); @@ -740,15 +859,18 @@ describe('Query operations', () => { }); it('should return extent when predefined', () => { - const response = FeatureServer.query({ - extent: { - xmin: -108, - ymin: 37, - xmax: -102, - ymax: 40, - spatialReference: { wkid: 4326 } - } - }, { returnExtentOnly: true }); + const response = FeatureServer.query( + { + extent: { + xmin: -108, + ymin: 37, + xmax: -102, + ymax: 40, + spatialReference: { wkid: 4326 }, + }, + }, + { returnExtentOnly: true }, + ); response.should.be.an.instanceOf(Object); response.should.have.property('extent'); response.extent.should.have.property('xmin', -108); @@ -760,16 +882,19 @@ describe('Query operations', () => { }); it('should return extent and count when both requested and predefined', () => { - const response = FeatureServer.query({ - count: 101, - extent: { - xmin: -108, - ymin: 37, - xmax: -102, - ymax: 40, - spatialReference: { wkid: 4326 } - } - }, { returnExtentOnly: true, returnCountOnly: true }); + const response = FeatureServer.query( + { + count: 101, + extent: { + xmin: -108, + ymin: 37, + xmax: -102, + ymax: 40, + spatialReference: { wkid: 4326 }, + }, + }, + { returnExtentOnly: true, returnCountOnly: true }, + ); response.should.be.an.instanceOf(Object); response.should.have.property('count', 101); response.should.have.property('extent'); diff --git a/packages/featureserver/test/integration/queryRelatedRecords.spec.js b/packages/featureserver/test/integration/queryRelatedRecords.spec.js index 07ae19af7..d9685c465 100644 --- a/packages/featureserver/test/integration/queryRelatedRecords.spec.js +++ b/packages/featureserver/test/integration/queryRelatedRecords.spec.js @@ -1,4 +1,4 @@ -const should = require('should') // eslint-disable-line +const should = require('should'); // eslint-disable-line const FeatureServer = require('../..'); const relatedData = require('./fixtures/relatedData.json'); const relatedDataCount = require('./fixtures/relatedDataCountProperty.json'); @@ -16,7 +16,9 @@ describe('QueryRelatedRecords operations', () => { }); it('should return count of features when returnCountOnly true in options', () => { - const response = FeatureServer.queryRelatedRecords(relatedData, { returnCountOnly: true }); + const response = FeatureServer.queryRelatedRecords(relatedData, { + returnCountOnly: true, + }); response.should.not.have.property('fields'); response.should.have.property('relatedRecordGroups'); response.relatedRecordGroups.should.have.length(1); @@ -26,7 +28,9 @@ describe('QueryRelatedRecords operations', () => { }); it('should return count when specified in properties and returnCountOnly true in options', () => { - const response = FeatureServer.queryRelatedRecords(relatedDataCount, { returnCountOnly: true }); + const response = FeatureServer.queryRelatedRecords(relatedDataCount, { + returnCountOnly: true, + }); response.should.not.have.property('fields'); response.should.have.property('relatedRecordGroups'); response.relatedRecordGroups.should.have.length(1); diff --git a/packages/featureserver/test/integration/schemas/index.js b/packages/featureserver/test/integration/schemas/index.js index 26022f9bf..ef0e0f22f 100644 --- a/packages/featureserver/test/integration/schemas/index.js +++ b/packages/featureserver/test/integration/schemas/index.js @@ -5,17 +5,17 @@ const featuresTemplateSchema = Joi.object().keys({ globalIdFieldName: Joi.string().valid(''), uniqueIdField: { name: 'OBJECTID', - isSystemMaintained: true + isSystemMaintained: true, }, hasZ: Joi.boolean().valid(false), hasM: Joi.boolean().valid(false), spatialReference: Joi.object().keys({ latestWkid: Joi.number().valid(4326), - wkid: Joi.number().valid(4326) + wkid: Joi.number().valid(4326), }), fields: Joi.array(), features: Joi.array(), - exceededTransferLimit: Joi.boolean().valid(false) + exceededTransferLimit: Joi.boolean().valid(false), }); const fieldsTemplateSchema = Joi.object().keys({ @@ -24,7 +24,7 @@ const fieldsTemplateSchema = Joi.object().keys({ alias: Joi.string(), sqlType: Joi.string().valid('sqlTypeOther'), domain: Joi.valid(null), - defaultValue: Joi.valid(null) + defaultValue: Joi.valid(null), }); const layerTemplateSchema = Joi.object().keys({ @@ -47,8 +47,8 @@ const layerTemplateSchema = Joi.object().keys({ ymax: Joi.number().valid(90), spatialReference: Joi.object().keys({ wkid: Joi.number().valid(4326), - latestWkid: Joi.number().valid(4326) - }) + latestWkid: Joi.number().valid(4326), + }), }), hasAttachments: Joi.boolean().valid(false), htmlPopupType: Joi.string().allow('esriServerHTMLPopupTypeNone'), @@ -64,7 +64,7 @@ const layerTemplateSchema = Joi.object().keys({ supportsAdvancedQueries: Joi.boolean().valid(true), supportedQueryFormats: Joi.string().allow('JSON'), ownershipBasedAccessControlForFeatures: Joi.object().keys({ - allowOthersToQuery: Joi.boolean().valid(true) + allowOthersToQuery: Joi.boolean().valid(true), }), supportsCoordinatesQuantization: Joi.boolean().valid(false), useStandardizedQueries: Joi.boolean().valid(true), @@ -76,7 +76,7 @@ const layerTemplateSchema = Joi.object().keys({ supportsPagination: Joi.boolean().valid(true), supportsTrueCurve: Joi.boolean().valid(false), supportsReturningQueryExtent: Joi.boolean().valid(true), - supportsQueryWithDistance: Joi.boolean().valid(true) + supportsQueryWithDistance: Joi.boolean().valid(true), }), dateFieldsTimeReference: null, isDataVersioned: Joi.boolean().valid(false), @@ -92,26 +92,40 @@ const layerTemplateSchema = Joi.object().keys({ timeInfo: Joi.object().keys({}), uniqueIdField: Joi.object().keys({ name: Joi.string().valid('OBJECTID'), - isSystemMaintained: Joi.boolean().valid(true) + isSystemMaintained: Joi.boolean().valid(true), }), - fields: Joi.array().items(Joi.object().keys({ - name: Joi.string(), - type: Joi.string().allow('esriFieldTypeOID', 'esriFieldTypeInteger', 'esriFieldTypeDouble', 'esriFieldTypeString', 'esriFieldTypeDate'), - alias: Joi.string(), - length: Joi.optional().when('type', { - is: Joi.string().allow('esriFieldTypeString', 'esriFieldTypeDate'), - then: Joi.number().integer().min(0) - }), - defaultValue: Joi.any().valid(null), - domain: Joi.any().valid(null), - editable: Joi.boolean().valid(false, true), - nullable: Joi.boolean().valid(false), - sqlType: Joi.string().valid('sqlTypeOther', 'sqlTypeDouble', 'sqlTypeInteger') - })).min(0), + fields: Joi.array() + .items( + Joi.object().keys({ + name: Joi.string(), + type: Joi.string().allow( + 'esriFieldTypeOID', + 'esriFieldTypeInteger', + 'esriFieldTypeDouble', + 'esriFieldTypeString', + 'esriFieldTypeDate', + ), + alias: Joi.string(), + length: Joi.optional().when('type', { + is: Joi.string().allow('esriFieldTypeString', 'esriFieldTypeDate'), + then: Joi.number().integer().min(0), + }), + defaultValue: Joi.any().valid(null), + domain: Joi.any().valid(null), + editable: Joi.boolean().valid(false, true), + nullable: Joi.boolean().valid(false), + sqlType: Joi.string().valid( + 'sqlTypeOther', + 'sqlTypeDouble', + 'sqlTypeInteger', + ), + }), + ) + .min(0), drawingInfo: Joi.object().keys({ renderer: Joi.object().keys({}), - labelingInfo: Joi.valid(null) - }) + labelingInfo: Joi.valid(null), + }), }); const oidTemplateSchema = Joi.object().keys({ @@ -120,7 +134,7 @@ const oidTemplateSchema = Joi.object().keys({ alias: Joi.string().valid('OBJECTID'), sqlType: Joi.string().valid('sqlTypeInteger'), domain: Joi.valid(null), - defaultValue: Joi.valid(null) + defaultValue: Joi.valid(null), }); const serverTemplateSchema = Joi.object().keys({ @@ -137,7 +151,7 @@ const serverTemplateSchema = Joi.object().keys({ copyrightText: Joi.string().allow(''), spatialReference: Joi.object().keys({ wkid: Joi.number().valid(4326), - latestWkid: Joi.number().valid(4326) + latestWkid: Joi.number().valid(4326), }), initialExtent: Joi.object().keys({ xmin: Joi.number().valid(-180), @@ -146,8 +160,8 @@ const serverTemplateSchema = Joi.object().keys({ ymax: Joi.number().valid(90), spatialReference: Joi.object().keys({ wkid: Joi.number().valid(4326), - latestWkid: Joi.number().valid(4326) - }) + latestWkid: Joi.number().valid(4326), + }), }), fullExtent: Joi.object().keys({ xmin: Joi.number().valid(-180), @@ -156,8 +170,8 @@ const serverTemplateSchema = Joi.object().keys({ ymax: Joi.number().valid(90), spatialReference: Joi.object().keys({ wkid: Joi.number().valid(4326), - latestWkid: Joi.number().valid(4326) - }) + latestWkid: Joi.number().valid(4326), + }), }), relationships: Joi.array(), allowGeometryUpdates: Joi.boolean().valid(false), @@ -165,7 +179,13 @@ const serverTemplateSchema = Joi.object().keys({ syncEnabled: Joi.boolean().valid(false), layers: Joi.array().min(0), tables: Joi.array().min(0), - supportsRelationshipsResource: Joi.boolean() + supportsRelationshipsResource: Joi.boolean(), }); -module.exports = { featuresTemplateSchema, fieldsTemplateSchema, layerTemplateSchema, oidTemplateSchema, serverTemplateSchema }; +module.exports = { + featuresTemplateSchema, + fieldsTemplateSchema, + layerTemplateSchema, + oidTemplateSchema, + serverTemplateSchema, +}; diff --git a/packages/logger/src/index.spec.js b/packages/logger/src/index.spec.js index 065c8b2ea..b082d9757 100644 --- a/packages/logger/src/index.spec.js +++ b/packages/logger/src/index.spec.js @@ -1,7 +1,7 @@ const test = require('tape'); const koopLogger = require('.'); -test('koop-logger', spec => { +test('koop-logger', (spec) => { try { const log = new koopLogger(); spec.ok(log); @@ -14,4 +14,4 @@ test('koop-logger', spec => { spec.fail(err); } spec.end(); -}); \ No newline at end of file +}); diff --git a/packages/output-geoservices/src/index.js b/packages/output-geoservices/src/index.js index 2b6414e7d..c072beae8 100644 --- a/packages/output-geoservices/src/index.js +++ b/packages/output-geoservices/src/index.js @@ -182,8 +182,13 @@ class GeoServices { ); } - FeatureServer.route(req, res, { owningSystemUrl: this.#buildOwningSystemUrl(req.headers.host, - req.baseUrl), authInfo }); + FeatureServer.route(req, res, { + owningSystemUrl: this.#buildOwningSystemUrl( + req.headers.host, + req.baseUrl, + ), + authInfo, + }); } #buildTokensUrl(host, baseUrl) { diff --git a/packages/output-geoservices/src/index.spec.js b/packages/output-geoservices/src/index.spec.js index aa8505ab9..82079f1b3 100644 --- a/packages/output-geoservices/src/index.spec.js +++ b/packages/output-geoservices/src/index.spec.js @@ -168,7 +168,7 @@ describe('Output Geoservices', () => { pull: jest.fn(async () => { const err = new Error('no token'); err.code = 401; - throw(err); + throw err; }), }; const output = new OutputGeoServices(modelMock, { logger: loggerMock }); diff --git a/packages/winnow/benchmark/index.js b/packages/winnow/benchmark/index.js index f8dfa93bf..96b941e8b 100644 --- a/packages/winnow/benchmark/index.js +++ b/packages/winnow/benchmark/index.js @@ -3,18 +3,20 @@ const fs = require('fs-extra'); const path = require('path'); const winnow = require('../src/index.js'); -const features = fs.readJSONSync(path.join(__dirname, './fixtures.geojson')).features; +const features = fs.readJSONSync( + path.join(__dirname, './fixtures.geojson'), +).features; const suite = new Benchmark.Suite(); suite .add('query all', function () { winnow.query(features, { - where: '1=1' + where: '1=1', }); }) .add('query with filter', function () { winnow.query(features, { - where: 'OBJECTID = \'east\'' + where: "OBJECTID = 'east'", }); }) .add('query with geo filter', function () { @@ -25,10 +27,10 @@ suite xmax: 80, ymax: 80, spatialReference: { - wkid: '4326' - } + wkid: '4326', + }, }, - spatialPredicate: 'ST_Within' + spatialPredicate: 'ST_Within', }); }) .on('cycle', function (event) { diff --git a/packages/winnow/src/calculate-class-breaks/filter-and-validate-classification-features.js b/packages/winnow/src/calculate-class-breaks/filter-and-validate-classification-features.js index 1151cfefe..446bea1fd 100644 --- a/packages/winnow/src/calculate-class-breaks/filter-and-validate-classification-features.js +++ b/packages/winnow/src/calculate-class-breaks/filter-and-validate-classification-features.js @@ -1,22 +1,29 @@ const _ = require('lodash'); -module.exports = function filterAndValidateClassificationFeatures (features, classificationField) { - return features.filter(feature => { - return !shouldSkipFeature({ feature, classificationField }); - }).map(feature => { - validateClassificationValue(feature, classificationField); - return Number(feature.properties[classificationField]); - }); +module.exports = function filterAndValidateClassificationFeatures( + features, + classificationField, +) { + return features + .filter((feature) => { + return !shouldSkipFeature({ feature, classificationField }); + }) + .map((feature) => { + validateClassificationValue(feature, classificationField); + return Number(feature.properties[classificationField]); + }); }; -function validateClassificationValue ({ properties }, classificationField) { +function validateClassificationValue({ properties }, classificationField) { const value = properties[classificationField]; if (_.isNaN(Number(value))) { - throw new TypeError(`Cannot use non-numeric classificationField, ${classificationField}: "${value}"`); + throw new TypeError( + `Cannot use non-numeric classificationField, ${classificationField}: "${value}"`, + ); } } -function shouldSkipFeature ({ feature: { properties }, classificationField }) { +function shouldSkipFeature({ feature: { properties }, classificationField }) { const value = properties[classificationField]; return value === undefined || value === null; } diff --git a/packages/winnow/src/errors.js b/packages/winnow/src/errors.js index d5c1a18db..f4d008d5c 100644 --- a/packages/winnow/src/errors.js +++ b/packages/winnow/src/errors.js @@ -1,5 +1,5 @@ class InvalidParameterError extends Error { - constructor (message) { + constructor(message) { super(message); this.code = 400; Error.captureStackTrace(this, InvalidParameterError); @@ -7,7 +7,7 @@ class InvalidParameterError extends Error { } class InvalidWhereParameterError extends Error { - constructor (message) { + constructor(message) { super(`Invalid "where" parameter: ${message}`); this.code = 400; @@ -17,4 +17,4 @@ class InvalidWhereParameterError extends Error { } } -module.exports = { InvalidParameterError, InvalidWhereParameterError }; \ No newline at end of file +module.exports = { InvalidParameterError, InvalidWhereParameterError }; diff --git a/packages/winnow/src/filter-and-transform/filter-and-transform.js b/packages/winnow/src/filter-and-transform/filter-and-transform.js index ec515b9bc..70d13b654 100644 --- a/packages/winnow/src/filter-and-transform/filter-and-transform.js +++ b/packages/winnow/src/filter-and-transform/filter-and-transform.js @@ -1,4 +1,10 @@ -const { within, contains, intersects, envelopeIntersects, hashedObjectIdComparator } = require('./filters'); +const { + within, + contains, + intersects, + envelopeIntersects, + hashedObjectIdComparator, +} = require('./filters'); const sql = require('alasql'); const { project, @@ -8,7 +14,7 @@ const { toEsriAttributes, toHash, toEsriGeometry, - reducePrecision + reducePrecision, } = require('./transforms'); sql.MAXSQLCACHESIZE = 0; diff --git a/packages/winnow/src/filter-and-transform/filter-and-transform.spec.js b/packages/winnow/src/filter-and-transform/filter-and-transform.spec.js index dbc20565d..fd0a7d10d 100644 --- a/packages/winnow/src/filter-and-transform/filter-and-transform.spec.js +++ b/packages/winnow/src/filter-and-transform/filter-and-transform.spec.js @@ -4,85 +4,68 @@ const polygonFilter = { type: 'Polygon', coordinates: [ [ - [ - -56.9, - -61.8 - ], - [ - -52.9, - -61.8 - ], - [ - -52.9, - -60.5 - ], - [ - -56.9, - -60.5 - ], - [ - -56.9, - -61.8 - ] - ] - ] + [-56.9, -61.8], + [-52.9, -61.8], + [-52.9, -60.5], + [-56.9, -60.5], + [-56.9, -61.8], + ], + ], }; const pointFeature = { type: 'Point', - coordinates: [ - -55.1, - -61.1 - ] + coordinates: [-55.1, -61.1], }; const lineFeature = { type: 'LineString', coordinates: [ - [ - -54.5, - -60.7 - ], - [ - -54.7, - -60.8 - ] - ] + [-54.5, -60.7], + [-54.7, -60.8], + ], }; const polygonFeature = { type: 'Polygon', coordinates: [ [ - [ - -54.3, - -61.3 - ], - [ - -53.9, - -61.3 - ], - [ - -53.9, - -60.7 - ], - [ - -54.3, - -61.3 - ] - ] - ] + [-54.3, -61.3], + [-53.9, -61.3], + [-53.9, -60.7], + [-54.3, -61.3], + ], + ], }; -test('sql.fn.ST_Within - geometries fully within a target polygon should return true', t => { +test('sql.fn.ST_Within - geometries fully within a target polygon should return true', (t) => { t.plan(3); - t.ok(filterAndTransform.fn.ST_Within(pointFeature, polygonFilter), 'point within filter geom'); - t.ok(filterAndTransform.fn.ST_Within(lineFeature, polygonFilter), 'line within filter geom'); - t.ok(filterAndTransform.fn.ST_Within(polygonFeature, polygonFilter), 'polygon within filter geom'); + t.ok( + filterAndTransform.fn.ST_Within(pointFeature, polygonFilter), + 'point within filter geom', + ); + t.ok( + filterAndTransform.fn.ST_Within(lineFeature, polygonFilter), + 'line within filter geom', + ); + t.ok( + filterAndTransform.fn.ST_Within(polygonFeature, polygonFilter), + 'polygon within filter geom', + ); }); -test('sql.fn.ST_Within - falsey feature geometries should return false', t => { - const falseyFeatures = [undefined, null, {}, { coordinates: [] }, { coordinates: [0, 0] }, { type: 'Point' }]; +test('sql.fn.ST_Within - falsey feature geometries should return false', (t) => { + const falseyFeatures = [ + undefined, + null, + {}, + { coordinates: [] }, + { coordinates: [0, 0] }, + { type: 'Point' }, + ]; - falseyFeatures.forEach(falsey => { - t.notOk(filterAndTransform.fn.ST_Within(falsey, polygonFilter), 'falsey feature should return false'); + falseyFeatures.forEach((falsey) => { + t.notOk( + filterAndTransform.fn.ST_Within(falsey, polygonFilter), + 'falsey feature should return false', + ); }); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/filters/contains.spec.js b/packages/winnow/src/filter-and-transform/filters/contains.spec.js index 084765295..9b1cdcc54 100644 --- a/packages/winnow/src/filter-and-transform/filters/contains.spec.js +++ b/packages/winnow/src/filter-and-transform/filters/contains.spec.js @@ -1,68 +1,90 @@ const test = require('tape'); const contains = require('./contains'); -test('contains: empty input', t => { +test('contains: empty input', (t) => { const result = contains(); t.equals(result, false); t.end(); }); -test('contains: empty object input', t => { +test('contains: empty object input', (t) => { const result = contains({}, {}); t.equals(result, false); t.end(); }); -test('contains: null input', t => { +test('contains: null input', (t) => { const result = contains(null, {}); t.equals(result, false); t.end(); }); -test('contains: null input', t => { +test('contains: null input', (t) => { const result = contains({}, null); t.equals(result, false); t.end(); }); -test('contains: missing geometry type', t => { +test('contains: missing geometry type', (t) => { const result = contains({ coordinates: [44, 84] }, {}); t.equals(result, false); t.end(); }); -test('contains: missing coordinates', t => { +test('contains: missing coordinates', (t) => { const result = contains({ type: 'Point' }, {}); t.equals(result, false); t.end(); }); -test('contains: missing empty coordinates', t => { +test('contains: missing empty coordinates', (t) => { const result = contains({ type: 'Point', coordinates: [] }, {}); t.equals(result, false); t.end(); }); -test('contains: missing filter geometry', t => { +test('contains: missing filter geometry', (t) => { const result = contains({ type: 'Point', coordinates: [44, -84.5] }); t.equals(result, false); t.end(); }); -test('contains: true', t => { - const result = contains({ type: 'Point', coordinates: [44, -84.5] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('contains: true', (t) => { + const result = contains( + { type: 'Point', coordinates: [44, -84.5] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); -test('contains: false', t => { - const result = contains({ type: 'Point', coordinates: [0, 0] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('contains: false', (t) => { + const result = contains( + { type: 'Point', coordinates: [0, 0] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, false); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/filters/envelope-intersects.js b/packages/winnow/src/filter-and-transform/filters/envelope-intersects.js index 10fccc0ec..a71a66139 100644 --- a/packages/winnow/src/filter-and-transform/filters/envelope-intersects.js +++ b/packages/winnow/src/filter-and-transform/filters/envelope-intersects.js @@ -1,31 +1,41 @@ const _ = require('lodash'); -const { calculateBounds, intersects, contains } = require('@terraformer/spatial'); +const { + calculateBounds, + intersects, + contains, +} = require('@terraformer/spatial'); const bboxPolygon = require('@turf/bbox-polygon').default; const { arcgisToGeoJSON } = require('@terraformer/arcgis'); module.exports = function (featureGeometry = {}, filterGeometry = {}) { if (_.isEmpty(featureGeometry) || _.isEmpty(filterGeometry)) return false; - const normalizedFeatureGeometry = isGeoJsonGeometry(featureGeometry) ? featureGeometry : arcgisToGeoJSON(featureGeometry); + const normalizedFeatureGeometry = isGeoJsonGeometry(featureGeometry) + ? featureGeometry + : arcgisToGeoJSON(featureGeometry); const { type, coordinates = [] } = normalizedFeatureGeometry; if (!type || coordinates.length === 0) return false; - const geometryFilterEnvelope = convertGeometryToEnvelopePolygon(filterGeometry); + const geometryFilterEnvelope = + convertGeometryToEnvelopePolygon(filterGeometry); - if (type === 'Point') return contains(geometryFilterEnvelope, normalizedFeatureGeometry); + if (type === 'Point') + return contains(geometryFilterEnvelope, normalizedFeatureGeometry); - const featureEnvelope = convertGeometryToEnvelopePolygon(normalizedFeatureGeometry); + const featureEnvelope = convertGeometryToEnvelopePolygon( + normalizedFeatureGeometry, + ); return intersects(geometryFilterEnvelope, featureEnvelope); }; -function convertGeometryToEnvelopePolygon (geometry) { +function convertGeometryToEnvelopePolygon(geometry) { const bounds = calculateBounds(geometry); const { geometry: envelopePolygon } = bboxPolygon(bounds); return envelopePolygon; } -function isGeoJsonGeometry ({ type, coordinates }) { +function isGeoJsonGeometry({ type, coordinates }) { return type && coordinates; } diff --git a/packages/winnow/src/filter-and-transform/filters/envelope-intersects.spec.js b/packages/winnow/src/filter-and-transform/filters/envelope-intersects.spec.js index 223ba95df..d71844d40 100644 --- a/packages/winnow/src/filter-and-transform/filters/envelope-intersects.spec.js +++ b/packages/winnow/src/filter-and-transform/filters/envelope-intersects.spec.js @@ -1,149 +1,161 @@ const test = require('tape'); const envelopeIntersects = require('./envelope-intersects'); -test('envelopeIntersects: empty input', t => { +test('envelopeIntersects: empty input', (t) => { const result = envelopeIntersects(); t.equals(result, false); t.end(); }); -test('envelopeIntersects: empty object input', t => { +test('envelopeIntersects: empty object input', (t) => { const result = envelopeIntersects({}, {}); t.equals(result, false); t.end(); }); -test('envelopeIntersects: null input', t => { +test('envelopeIntersects: null input', (t) => { const result = envelopeIntersects(null, {}); t.equals(result, false); t.end(); }); -test('envelopeIntersects: null input', t => { +test('envelopeIntersects: null input', (t) => { const result = envelopeIntersects({}, null); t.equals(result, false); t.end(); }); -test('envelopeIntersects: missing geometry type', t => { +test('envelopeIntersects: missing geometry type', (t) => { const result = envelopeIntersects({ coordinates: [44, 84] }, {}); t.equals(result, false); t.end(); }); -test('envelopeIntersects: missing coordinates', t => { +test('envelopeIntersects: missing coordinates', (t) => { const result = envelopeIntersects({ type: 'Point' }, {}); t.equals(result, false); t.end(); }); -test('envelopeIntersects: missing empty coordinates', t => { +test('envelopeIntersects: missing empty coordinates', (t) => { const result = envelopeIntersects({ type: 'Point', coordinates: [] }, {}); t.equals(result, false); t.end(); }); -test('envelopeIntersects: missing filter geometry', t => { - const result = envelopeIntersects({ type: 'Point', coordinates: [44, -84.5] }); +test('envelopeIntersects: missing filter geometry', (t) => { + const result = envelopeIntersects({ + type: 'Point', + coordinates: [44, -84.5], + }); t.equals(result, false); t.end(); }); -test('envelopeIntersects: Point inside polygon, true', t => { - const result = envelopeIntersects({ type: 'Point', coordinates: [44, -84.5] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('envelopeIntersects: Point inside polygon, true', (t) => { + const result = envelopeIntersects( + { type: 'Point', coordinates: [44, -84.5] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); -test('envelopeIntersects: LineString outside polygon, false', t => { - const result = envelopeIntersects({ type: 'LineString', coordinates: [[17.41, 52.22], [17.42, 52.22]] }, { - type: 'Polygon', - coordinates: [[[17.2, 52.2], [17.4, 52.2], [17.4, 52.3], [17.2, 52.3], [17.2, 52.2]]] - }); +test('envelopeIntersects: LineString outside polygon, false', (t) => { + const result = envelopeIntersects( + { + type: 'LineString', + coordinates: [ + [17.41, 52.22], + [17.42, 52.22], + ], + }, + { + type: 'Polygon', + coordinates: [ + [ + [17.2, 52.2], + [17.4, 52.2], + [17.4, 52.3], + [17.2, 52.3], + [17.2, 52.2], + ], + ], + }, + ); t.equals(result, false); t.end(); }); -test('envelopeIntersects: Point inside polygon, Esri Geometry, true', t => { - const result = envelopeIntersects({ x: 44, y: -84.5 }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('envelopeIntersects: Point inside polygon, Esri Geometry, true', (t) => { + const result = envelopeIntersects( + { x: 44, y: -84.5 }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); -test('envelopeIntersects: Point inside polygon envelope, true', t => { - const result = envelopeIntersects({ type: 'Point', coordinates: [17.505, 52.029] }, { - type: 'Polygon', - coordinates: [ - [ - [ - 17.52, - 52.037 - ], - [ - 17.50, - 52.02 - ], - [ - 17.55134582519531, - 52.01 - ], - [ - 17.56988525390625, - 52.02 - ], +test('envelopeIntersects: Point inside polygon envelope, true', (t) => { + const result = envelopeIntersects( + { type: 'Point', coordinates: [17.505, 52.029] }, + { + type: 'Polygon', + coordinates: [ [ - 17.538986206054688, - 52.03 + [17.52, 52.037], + [17.5, 52.02], + [17.55134582519531, 52.01], + [17.56988525390625, 52.02], + [17.538986206054688, 52.03], + [17.52, 52.037], ], - [ - 17.52, - 52.037 - ] - ] - ] - }); + ], + }, + ); t.equals(result, true); t.end(); }); -test('envelopeIntersects: Point outside polygon envelope, false', t => { - const result = envelopeIntersects({ type: 'Point', coordinates: [20, 53] }, { - type: 'Polygon', - coordinates: [ - [ - [ - 17.52, - 52.037 - ], +test('envelopeIntersects: Point outside polygon envelope, false', (t) => { + const result = envelopeIntersects( + { type: 'Point', coordinates: [20, 53] }, + { + type: 'Polygon', + coordinates: [ [ - 17.50, - 52.02 + [17.52, 52.037], + [17.5, 52.02], + [17.55134582519531, 52.01], + [17.56988525390625, 52.02], + [17.538986206054688, 52.03], + [17.52, 52.037], ], - [ - 17.55134582519531, - 52.01 - ], - [ - 17.56988525390625, - 52.02 - ], - [ - 17.538986206054688, - 52.03 - ], - [ - 17.52, - 52.037 - ] - ] - ] - }); + ], + }, + ); t.equals(result, false); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.js b/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.js index a4cd58e2b..9ade60427 100644 --- a/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.js +++ b/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.js @@ -14,8 +14,10 @@ const logManager = require('../../log-manager'); * @param {*} operator the predicate operator */ module.exports = function (properties, geometry, value, operator) { - const hashedFeature = createIntegerHash(JSON.stringify({ properties, geometry })); - + const hashedFeature = createIntegerHash( + JSON.stringify({ properties, geometry }), + ); + if (operator === '=' && hashedFeature === value) { return true; } @@ -39,12 +41,12 @@ module.exports = function (properties, geometry, value, operator) { if (operator === '<=' && hashedFeature <= value) { return true; } - + if (operator === 'IN') { const objectIdValues = value.split(',').map(Number); return objectIdValues.includes(hashedFeature); } - + logManager.logger.debug(`unsupported operator "${operator}"; ignoring`); return false; }; diff --git a/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.spec.js b/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.spec.js index ac95f831a..1ec44f530 100644 --- a/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.spec.js +++ b/packages/winnow/src/filter-and-transform/filters/hashed-objectid-comparator.spec.js @@ -6,50 +6,65 @@ const properties = { foo: 'bar' }; const geometry = { type: 'Point', coordinates: [44, -84.5] }; const objectId = createIntegerHash(JSON.stringify({ properties, geometry })); -test('hashedObjectIdComparator: =, should return true', t => { +test('hashedObjectIdComparator: =, should return true', (t) => { const result = hashedObjectIdComparator(properties, geometry, objectId, '='); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: !=, should return true', t => { +test('hashedObjectIdComparator: !=, should return true', (t) => { const result = hashedObjectIdComparator(properties, geometry, -9999, '!='); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: >, should return true', t => { +test('hashedObjectIdComparator: >, should return true', (t) => { const result = hashedObjectIdComparator(properties, geometry, 0, '>'); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: >=, should return true', t => { +test('hashedObjectIdComparator: >=, should return true', (t) => { const result = hashedObjectIdComparator(properties, geometry, 0, '>='); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: >, should return true', t => { - const result = hashedObjectIdComparator(properties, geometry, 9999999999, '<'); +test('hashedObjectIdComparator: >, should return true', (t) => { + const result = hashedObjectIdComparator( + properties, + geometry, + 9999999999, + '<', + ); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: >=, should return true', t => { - const result = hashedObjectIdComparator(properties, geometry, 9999999999, '<='); +test('hashedObjectIdComparator: >=, should return true', (t) => { + const result = hashedObjectIdComparator( + properties, + geometry, + 9999999999, + '<=', + ); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: IN, should return true', t => { - const result = hashedObjectIdComparator(properties, geometry, `${objectId},0000`, 'IN'); +test('hashedObjectIdComparator: IN, should return true', (t) => { + const result = hashedObjectIdComparator( + properties, + geometry, + `${objectId},0000`, + 'IN', + ); t.equals(result, true); t.end(); }); -test('hashedObjectIdComparator: unsupported operator', t => { +test('hashedObjectIdComparator: unsupported operator', (t) => { const result = hashedObjectIdComparator(properties, geometry, 0, '***'); t.equals(result, false); t.end(); -}); \ No newline at end of file +}); diff --git a/packages/winnow/src/filter-and-transform/filters/index.js b/packages/winnow/src/filter-and-transform/filters/index.js index 79cb94fcf..63c519579 100644 --- a/packages/winnow/src/filter-and-transform/filters/index.js +++ b/packages/winnow/src/filter-and-transform/filters/index.js @@ -3,5 +3,5 @@ module.exports = { contains: require('./contains'), intersects: require('./intersects'), envelopeIntersects: require('./envelope-intersects'), - hashedObjectIdComparator: require('./hashed-objectid-comparator') + hashedObjectIdComparator: require('./hashed-objectid-comparator'), }; diff --git a/packages/winnow/src/filter-and-transform/filters/intersects.js b/packages/winnow/src/filter-and-transform/filters/intersects.js index 12e2c5155..779b3b430 100644 --- a/packages/winnow/src/filter-and-transform/filters/intersects.js +++ b/packages/winnow/src/filter-and-transform/filters/intersects.js @@ -4,13 +4,15 @@ const { arcgisToGeoJSON } = require('@terraformer/arcgis'); module.exports = function (featureGeometry = {}, filterGeometry = {}) { if (_.isEmpty(featureGeometry)) return false; - const geometry = isGeoJsonGeometry(featureGeometry) ? featureGeometry : arcgisToGeoJSON(featureGeometry); + const geometry = isGeoJsonGeometry(featureGeometry) + ? featureGeometry + : arcgisToGeoJSON(featureGeometry); const { type, coordinates = [] } = geometry; if (!type || !coordinates || coordinates.length === 0) return false; if (type === 'Point') return contains(filterGeometry, geometry); return intersects(filterGeometry, geometry); }; -function isGeoJsonGeometry ({ type, coordinates }) { +function isGeoJsonGeometry({ type, coordinates }) { return type && coordinates; } diff --git a/packages/winnow/src/filter-and-transform/filters/intersects.spec.js b/packages/winnow/src/filter-and-transform/filters/intersects.spec.js index c79a4d2ae..af1d88a5c 100644 --- a/packages/winnow/src/filter-and-transform/filters/intersects.spec.js +++ b/packages/winnow/src/filter-and-transform/filters/intersects.spec.js @@ -1,77 +1,116 @@ const test = require('tape'); const intersects = require('./intersects'); -test('intersects: empty input', t => { +test('intersects: empty input', (t) => { const result = intersects(); t.equals(result, false); t.end(); }); -test('intersects: empty object input', t => { +test('intersects: empty object input', (t) => { const result = intersects({}, {}); t.equals(result, false); t.end(); }); -test('intersects: null input', t => { +test('intersects: null input', (t) => { const result = intersects(null, {}); t.equals(result, false); t.end(); }); -test('intersects: null input', t => { +test('intersects: null input', (t) => { const result = intersects({}, null); t.equals(result, false); t.end(); }); -test('intersects: missing geometry type', t => { +test('intersects: missing geometry type', (t) => { const result = intersects({ coordinates: [44, 84] }, {}); t.equals(result, false); t.end(); }); -test('intersects: missing coordinates', t => { +test('intersects: missing coordinates', (t) => { const result = intersects({ type: 'Point' }, {}); t.equals(result, false); t.end(); }); -test('intersects: missing empty coordinates', t => { +test('intersects: missing empty coordinates', (t) => { const result = intersects({ type: 'Point', coordinates: [] }, {}); t.equals(result, false); t.end(); }); -test('intersects: missing filter geometry', t => { +test('intersects: missing filter geometry', (t) => { const result = intersects({ type: 'Point', coordinates: [44, -84.5] }); t.equals(result, false); t.end(); }); -test('intersects: Point inside polygon, true', t => { - const result = intersects({ type: 'Point', coordinates: [44, -84.5] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('intersects: Point inside polygon, true', (t) => { + const result = intersects( + { type: 'Point', coordinates: [44, -84.5] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); -test('intersects: LineString outside polygon, false', t => { - const result = intersects({ type: 'LineString', coordinates: [[17.41, 52.22], [17.42, 52.22]] }, { - type: 'Polygon', - coordinates: [[[17.2, 52.2], [17.4, 52.2], [17.4, 52.3], [17.2, 52.3], [17.2, 52.2]]] - }); +test('intersects: LineString outside polygon, false', (t) => { + const result = intersects( + { + type: 'LineString', + coordinates: [ + [17.41, 52.22], + [17.42, 52.22], + ], + }, + { + type: 'Polygon', + coordinates: [ + [ + [17.2, 52.2], + [17.4, 52.2], + [17.4, 52.3], + [17.2, 52.3], + [17.2, 52.2], + ], + ], + }, + ); t.equals(result, false); t.end(); }); -test('intersects: Point inside polygon, Esri Geometry, true', t => { - const result = intersects({ x: 44, y: -84.5 }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('intersects: Point inside polygon, Esri Geometry, true', (t) => { + const result = intersects( + { x: 44, y: -84.5 }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/filters/within.spec.js b/packages/winnow/src/filter-and-transform/filters/within.spec.js index b514f82da..4e4f9a329 100644 --- a/packages/winnow/src/filter-and-transform/filters/within.spec.js +++ b/packages/winnow/src/filter-and-transform/filters/within.spec.js @@ -1,68 +1,90 @@ const test = require('tape'); const within = require('./within'); -test('within: empty input', t => { +test('within: empty input', (t) => { const result = within(); t.equals(result, false); t.end(); }); -test('within: empty object input', t => { +test('within: empty object input', (t) => { const result = within({}, {}); t.equals(result, false); t.end(); }); -test('within: null input', t => { +test('within: null input', (t) => { const result = within(null, {}); t.equals(result, false); t.end(); }); -test('within: null input', t => { +test('within: null input', (t) => { const result = within({}, null); t.equals(result, false); t.end(); }); -test('within: missing geometry type', t => { +test('within: missing geometry type', (t) => { const result = within({ coordinates: [44, 84] }, {}); t.equals(result, false); t.end(); }); -test('within: missing coordinates', t => { +test('within: missing coordinates', (t) => { const result = within({ type: 'Point' }, {}); t.equals(result, false); t.end(); }); -test('within: missing empty coordinates', t => { +test('within: missing empty coordinates', (t) => { const result = within({ type: 'Point', coordinates: [] }, {}); t.equals(result, false); t.end(); }); -test('within: missing filter geometry', t => { +test('within: missing filter geometry', (t) => { const result = within({ type: 'Point', coordinates: [44, -84.5] }); t.equals(result, false); t.end(); }); -test('within: true', t => { - const result = within({ type: 'Point', coordinates: [44, -84.5] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('within: true', (t) => { + const result = within( + { type: 'Point', coordinates: [44, -84.5] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, true); t.end(); }); -test('within: false', t => { - const result = within({ type: 'Point', coordinates: [0, 0] }, { - type: 'Polygon', - coordinates: [[[44, -85], [45, -85], [45, -84], [44, -84], [44, -85]]] - }); +test('within: false', (t) => { + const result = within( + { type: 'Point', coordinates: [0, 0] }, + { + type: 'Polygon', + coordinates: [ + [ + [44, -85], + [45, -85], + [45, -84], + [44, -84], + [44, -85], + ], + ], + }, + ); t.equals(result, false); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.js b/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.js index 86dda5faa..b33b4a316 100644 --- a/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.js +++ b/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.js @@ -1,8 +1,8 @@ const hashFunction = require('./hash-function'); -module.exports = function createIntegerHash (inputStr) { +module.exports = function createIntegerHash(inputStr) { // Hash to 32 bit unsigned integer const hash = hashFunction(inputStr); // Normalize to range of postive values of signed integer - return Math.round((hash / 4294967295) * (2147483647)); + return Math.round((hash / 4294967295) * 2147483647); }; diff --git a/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.spec.js b/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.spec.js index c13fe27d4..578d180b9 100644 --- a/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.spec.js +++ b/packages/winnow/src/filter-and-transform/helpers/create-integer-hash.spec.js @@ -2,12 +2,12 @@ const test = require('tape'); const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './create-integer-hash'; -test('numeric hash 32 function', t => { +test('numeric hash 32 function', (t) => { const hashFunctionSpy = sinon.spy(function () { return 4294967295; }); const createIntegerHash = proxyquire(modulePath, { - './hash-function': hashFunctionSpy + './hash-function': hashFunctionSpy, }); const result = createIntegerHash('my-string'); diff --git a/packages/winnow/src/filter-and-transform/helpers/hash-function.js b/packages/winnow/src/filter-and-transform/helpers/hash-function.js index 6227564e4..a29c22a8e 100644 --- a/packages/winnow/src/filter-and-transform/helpers/hash-function.js +++ b/packages/winnow/src/filter-and-transform/helpers/hash-function.js @@ -1,8 +1,9 @@ const hashFixture = require('./hash-fixture'); -const USE_JAVASCRIPT_HASHING = process.env.OBJECTID_FEATURE_HASH === 'javascript'; +const USE_JAVASCRIPT_HASHING = + process.env.OBJECTID_FEATURE_HASH === 'javascript'; const murmurhash = require('murmurhash'); -function getHashFunction () { +function getHashFunction() { if (USE_JAVASCRIPT_HASHING) { return murmurhash; } @@ -12,7 +13,11 @@ function getHashFunction () { const hashFunction = require('farmhash').hash32; hashFunction(JSON.stringify(hashFixture)); return hashFunction; + // eslint-disable-next-line } catch (e) { + console.info( + 'Using murmurhash as default hasher for OBJECTID auto-generate.', + ); return murmurhash; } } diff --git a/packages/winnow/src/filter-and-transform/helpers/hash-function.spec.js b/packages/winnow/src/filter-and-transform/helpers/hash-function.spec.js index 26c6eb69a..262fafa16 100644 --- a/packages/winnow/src/filter-and-transform/helpers/hash-function.spec.js +++ b/packages/winnow/src/filter-and-transform/helpers/hash-function.spec.js @@ -2,13 +2,17 @@ const test = require('tape'); const proxyquire = require('proxyquire'); const modulePath = './hash-function'; const stub = { - 'murmurhash': () => { return 'murmurhash'; }, - 'farmhash': { // eslint-disable-line - hash32: () => { return 'farmhash'; } - } + murmurhash: () => { + return 'murmurhash'; + }, + farmhash: { + hash32: () => { + return 'farmhash'; + }, + }, }; -test('hashFunction: ENV variable forces use of murmurhash', t => { +test('hashFunction: ENV variable forces use of murmurhash', (t) => { t.plan(1); process.env.OBJECTID_FEATURE_HASH = 'javascript'; const hashFunction = proxyquire(modulePath, stub); @@ -16,19 +20,23 @@ test('hashFunction: ENV variable forces use of murmurhash', t => { process.env.OBJECTID_FEATURE_HASH = undefined; }); -test('hashFunction: default use of farmhash', t => { +test('hashFunction: default use of farmhash', (t) => { t.plan(1); const hashFunction = proxyquire(modulePath, stub); t.equals(hashFunction(), 'farmhash'); }); -test('hashFunction: fallback use of murmurhash', t => { +test('hashFunction: fallback use of murmurhash', (t) => { t.plan(1); const stub = { - 'murmurhash': () => { return 'murmurhash'; }, - 'farmhash': { // eslint-disable-line - hash32: () => { throw new Error(); } - } + murmurhash: () => { + return 'murmurhash'; + }, + farmhash: { + hash32: () => { + throw new Error(); + }, + }, }; const hashFunction = proxyquire(modulePath, stub); t.equals(hashFunction(), 'murmurhash'); diff --git a/packages/winnow/src/filter-and-transform/helpers/index.js b/packages/winnow/src/filter-and-transform/helpers/index.js index ebdf320a0..fece6a06e 100644 --- a/packages/winnow/src/filter-and-transform/helpers/index.js +++ b/packages/winnow/src/filter-and-transform/helpers/index.js @@ -1,4 +1,4 @@ module.exports = { createIntegerHash: require('./create-integer-hash'), - hashFunction: require('./hash-function') + hashFunction: require('./hash-function'), }; diff --git a/packages/winnow/src/filter-and-transform/index.js b/packages/winnow/src/filter-and-transform/index.js index 756d2725c..b76daab50 100644 --- a/packages/winnow/src/filter-and-transform/index.js +++ b/packages/winnow/src/filter-and-transform/index.js @@ -1,4 +1,4 @@ module.exports = { filterAndTransform: require('./filter-and-transform'), - prepareFilterAndTransform: require('./prepare-filter-and-transform') + prepareFilterAndTransform: require('./prepare-filter-and-transform'), }; diff --git a/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.js b/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.js index a6fa5d5e8..6da0cbdea 100644 --- a/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.js +++ b/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.js @@ -8,22 +8,23 @@ module.exports = function (statement) { }; }; -function normalizeParams (inParams) { +function normalizeParams(inParams) { let params; // If this is just a passed in feature if (!inParams.length) params = [[inParams]]; // If this is an array of features - if (isGeoJSONFeatures(inParams) || isEsriFeatures(inParams)) params = [inParams]; + if (isGeoJSONFeatures(inParams) || isEsriFeatures(inParams)) + params = [inParams]; return params; } -function isGeoJSONFeatures (candidate) { +function isGeoJSONFeatures(candidate) { const feature = candidate[0] || {}; if (feature.type && feature.type.toLowerCase() === 'feature') return true; else return false; } -function isEsriFeatures (candidate) { +function isEsriFeatures(candidate) { const feature = candidate[0] || {}; if (feature.attributes || feature.geometry) return true; else return false; diff --git a/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.spec.js b/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.spec.js index ca4b2a5f9..ad347735e 100644 --- a/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.spec.js +++ b/packages/winnow/src/filter-and-transform/prepare-filter-and-transform.spec.js @@ -3,7 +3,7 @@ const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './prepare-filter-and-transform'; -test('Should return prepared filter and transform query', t => { +test('Should return prepared filter and transform query', (t) => { const compiledQuerySpy = sinon.spy(() => { return 'results'; }); @@ -11,15 +11,16 @@ test('Should return prepared filter and transform query', t => { const filterAndTransform = sinon.spy({ compile: function () { return compiledQuerySpy; - } + }, }); const prepareFilterAndTransform = proxyquire(modulePath, { - './filter-and-transform': filterAndTransform + './filter-and-transform': filterAndTransform, }); // Get a prepared filter and transform query - const preparedFilterAndTransform = prepareFilterAndTransform('SELECT foo FROM ?'); + const preparedFilterAndTransform = + prepareFilterAndTransform('SELECT foo FROM ?'); t.equals(typeof preparedFilterAndTransform, 'function'); // Execute with single GeoJSON feature diff --git a/packages/winnow/src/filter-and-transform/transforms/index.js b/packages/winnow/src/filter-and-transform/transforms/index.js index e7439fc34..262c4961e 100644 --- a/packages/winnow/src/filter-and-transform/transforms/index.js +++ b/packages/winnow/src/filter-and-transform/transforms/index.js @@ -6,5 +6,5 @@ module.exports = { toEsriAttributes: require('./to-esri-attributes'), toHash: require('./to-hash'), toEsriGeometry: require('./to-esri-geometry'), - reducePrecision: require('./reduce-precision') + reducePrecision: require('./reduce-precision'), }; diff --git a/packages/winnow/src/filter-and-transform/transforms/project.js b/packages/winnow/src/filter-and-transform/transforms/project.js index 9c88357ce..ad4fa7627 100644 --- a/packages/winnow/src/filter-and-transform/transforms/project.js +++ b/packages/winnow/src/filter-and-transform/transforms/project.js @@ -1,25 +1,35 @@ const logManager = require('../../log-manager'); const projectCoordinates = require('../../helpers/project-coordinates'); -function project (geometry, sourceCoordinateSystem, targetCoordinateSystem) { +function project(geometry, sourceCoordinateSystem, targetCoordinateSystem) { if (!geometry || !targetCoordinateSystem) return geometry; const { type, coordinates: sourceCoordinates } = geometry; if (!type || !sourceCoordinates) return geometry; - return tryProjectingGeometry({ type, sourceCoordinates, sourceCoordinateSystem, targetCoordinateSystem }); + return tryProjectingGeometry({ + type, + sourceCoordinates, + sourceCoordinateSystem, + targetCoordinateSystem, + }); } -function tryProjectingGeometry ({ type, sourceCoordinates, sourceCoordinateSystem, targetCoordinateSystem }) { +function tryProjectingGeometry({ + type, + sourceCoordinates, + sourceCoordinateSystem, + targetCoordinateSystem, +}) { try { return { type, coordinates: projectCoordinates({ coordinates: sourceCoordinates, fromSR: sourceCoordinateSystem, - toSR: targetCoordinateSystem - }) + toSR: targetCoordinateSystem, + }), }; } catch (error) { logManager.logger.debug(error); diff --git a/packages/winnow/src/filter-and-transform/transforms/project.spec.js b/packages/winnow/src/filter-and-transform/transforms/project.spec.js index f65993783..0d9b76345 100644 --- a/packages/winnow/src/filter-and-transform/transforms/project.spec.js +++ b/packages/winnow/src/filter-and-transform/transforms/project.spec.js @@ -4,60 +4,72 @@ const proxyquire = require('proxyquire'); const project = require('./project'); const modulePath = './project'; -test('project, empty input, returns undefined', t => { +test('project, empty input, returns undefined', (t) => { const result = project(); t.equals(result, undefined); t.end(); }); -test('project, empty target coordinate system input, returns input geometry', t => { +test('project, empty target coordinate system input, returns input geometry', (t) => { const result = project({}); t.deepEquals(result, {}); t.end(); }); -test('project, empty geometry object, return input geometry', t => { +test('project, empty geometry object, return input geometry', (t) => { const result = project({}, 'coordinate-system'); t.deepEquals(result, {}); t.end(); }); -test('project, missing input geometry coordinates, return input geometry', t => { +test('project, missing input geometry coordinates, return input geometry', (t) => { const result = project({ type: 'Point' }, 'coordinate-system'); t.deepEquals(result, { type: 'Point' }); t.end(); }); -test('project, missing input geometry type, return input geometry', t => { +test('project, missing input geometry type, return input geometry', (t) => { const result = project({ coordinates: [] }, 'coordinate-system'); t.deepEquals(result, { coordinates: [] }); t.end(); }); -test('project, valid input, return projection result', t => { - const projectSpy = sinon.spy(function () { return 'projected-coordinates'; }); +test('project, valid input, return projection result', (t) => { + const projectSpy = sinon.spy(function () { + return 'projected-coordinates'; + }); const project = proxyquire(modulePath, { - '../../helpers/project-coordinates': projectSpy + '../../helpers/project-coordinates': projectSpy, }); - const result = project({ type: 'Point', coordinates: 'source-coordinates' }, 'source-cs', 'target-cs'); + const result = project( + { type: 'Point', coordinates: 'source-coordinates' }, + 'source-cs', + 'target-cs', + ); t.deepEquals(result, { type: 'Point', coordinates: 'projected-coordinates' }); t.ok(projectSpy.calledOnce); - t.deepEquals(projectSpy.firstCall.args, [{ - coordinates: 'source-coordinates', - fromSR: 'source-cs', - toSR: 'target-cs' - }]); + t.deepEquals(projectSpy.firstCall.args, [ + { + coordinates: 'source-coordinates', + fromSR: 'source-cs', + toSR: 'target-cs', + }, + ]); t.end(); }); -test('project, error throw in projection, return null', t => { +test('project, error throw in projection, return null', (t) => { const projectSpy = sinon.spy(function () { throw new Error('project error'); }); const project = proxyquire(modulePath, { - '../../helpers/project-coordinates': projectSpy + '../../helpers/project-coordinates': projectSpy, }); - const result = project({ type: 'Point', coordinates: [] }, 'source-cs', 'target-cs'); + const result = project( + { type: 'Point', coordinates: [] }, + 'source-cs', + 'target-cs', + ); t.deepEquals(result, null); t.end(); }); diff --git a/packages/winnow/src/filter-and-transform/transforms/reduce-precision.js b/packages/winnow/src/filter-and-transform/transforms/reduce-precision.js index bb8d3bb4d..588472cf7 100644 --- a/packages/winnow/src/filter-and-transform/transforms/reduce-precision.js +++ b/packages/winnow/src/filter-and-transform/transforms/reduce-precision.js @@ -9,14 +9,18 @@ module.exports = function (geometry, precision) { return { type, - coordinates: reducePrecision(coordinates, precision) + coordinates: reducePrecision(coordinates, precision), }; }; -function reducePrecision (coordinates, precision) { - return transformCoordinates(coordinates, { precision }, (coordinates, { precision }) => { - return coordinates.map(position => { - return parseFloat(position.toFixed(precision)); - }); - }); +function reducePrecision(coordinates, precision) { + return transformCoordinates( + coordinates, + { precision }, + (coordinates, { precision }) => { + return coordinates.map((position) => { + return parseFloat(position.toFixed(precision)); + }); + }, + ); } diff --git a/packages/winnow/src/filter-and-transform/transforms/reduce-precision.spec.js b/packages/winnow/src/filter-and-transform/transforms/reduce-precision.spec.js index 61262ba2b..ea8d6d6d9 100644 --- a/packages/winnow/src/filter-and-transform/transforms/reduce-precision.spec.js +++ b/packages/winnow/src/filter-and-transform/transforms/reduce-precision.spec.js @@ -3,28 +3,28 @@ const reducePrecision = require('./reduce-precision'); const inputFixture = { type: 'Point', - coordinates: [100.011189, 0.123451] + coordinates: [100.011189, 0.123451], }; -test('reducePrecision, empty input, returns undefined', t => { +test('reducePrecision, empty input, returns undefined', (t) => { const result = reducePrecision(); t.equals(result, undefined); t.end(); }); -test('reducePrecision, empty geometry, returns empty geometry', t => { +test('reducePrecision, empty geometry, returns empty geometry', (t) => { const result = reducePrecision({}); t.deepEquals(result, {}); t.end(); }); -test('reducePrecision, no precision input', t => { +test('reducePrecision, no precision input', (t) => { const result = reducePrecision(inputFixture); t.deepEquals(result, { type: 'Point', coordinates: [100, 0] }); t.end(); }); -test('reducePrecision', t => { +test('reducePrecision', (t) => { const result = reducePrecision(inputFixture, 3); t.deepEquals(result, { type: 'Point', coordinates: [100.011, 0.123] }); t.end(); diff --git a/packages/winnow/src/filter-and-transform/transforms/select-fields-to-esri-attributes.js b/packages/winnow/src/filter-and-transform/transforms/select-fields-to-esri-attributes.js index 8389eb72b..142adea8b 100644 --- a/packages/winnow/src/filter-and-transform/transforms/select-fields-to-esri-attributes.js +++ b/packages/winnow/src/filter-and-transform/transforms/select-fields-to-esri-attributes.js @@ -1,8 +1,21 @@ const _ = require('lodash'); const toEsriAttributes = require('./to-esri-attributes'); -function selectFieldsToEsriAttributes (properties, geometry, delimitedFields, dateFields, requiresObjectId, idField) { - const transformedProperties = toEsriAttributes(properties, geometry, dateFields, requiresObjectId, idField); +function selectFieldsToEsriAttributes( + properties, + geometry, + delimitedFields, + dateFields, + requiresObjectId, + idField, +) { + const transformedProperties = toEsriAttributes( + properties, + geometry, + dateFields, + requiresObjectId, + idField, + ); const fields = delimitedFields.split(','); return _.pick(transformedProperties, fields); } diff --git a/packages/winnow/src/filter-and-transform/transforms/select-fields.js b/packages/winnow/src/filter-and-transform/transforms/select-fields.js index ca5e417b7..f20e954d9 100644 --- a/packages/winnow/src/filter-and-transform/transforms/select-fields.js +++ b/packages/winnow/src/filter-and-transform/transforms/select-fields.js @@ -1,6 +1,6 @@ const _ = require('lodash'); -function selectFields (properties, delimitedFields) { +function selectFields(properties, delimitedFields) { const fields = delimitedFields.split(','); return _.pick(properties, fields); } diff --git a/packages/winnow/src/filter-and-transform/transforms/to-esri-attributes.js b/packages/winnow/src/filter-and-transform/transforms/to-esri-attributes.js index 65b24c8ff..fa6259509 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-esri-attributes.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-esri-attributes.js @@ -2,7 +2,13 @@ const _ = require('lodash'); const logManager = require('../../log-manager'); const { createIntegerHash } = require('../helpers'); -module.exports = function transformToEsriProperties (properties, geometry, delimitedDateFields, requiresObjectId, idField) { +module.exports = function transformToEsriProperties( + properties, + geometry, + delimitedDateFields, + requiresObjectId, + idField, +) { requiresObjectId = requiresObjectId === 'true'; idField = idField === 'null' ? null : idField; @@ -10,41 +16,57 @@ module.exports = function transformToEsriProperties (properties, geometry, delim if (requiresObjectId && !idField) { properties = injectObjectId({ properties, geometry }); - } else if (requiresObjectId && shouldLogIdFieldDataTypeWarning(properties[idField])) { - logManager.logger.debug(`Unique-identifier ("${idField}") has a value (${properties[idField]}) that is not an integer-type, it is a ${typeof properties[idField]}; this may cause problems in some clients.`); - } else if (requiresObjectId && shouldLogIdFieldRangeWarning(properties[idField])) { - logManager.logger.debug(`Unique-identifier ("${idField}") has a value (${properties[idField]}) that is not a valid integer range (0 to ${Number.MAX_SAFE_INTEGER}); this may cause problems in some clients.`); + } else if ( + requiresObjectId && + shouldLogIdFieldDataTypeWarning(properties[idField]) + ) { + logManager.logger.debug( + `Unique-identifier ("${idField}") has a value (${properties[idField]}) that is not an integer-type, it is a ${typeof properties[idField]}; this may cause problems in some clients.`, + ); + } else if ( + requiresObjectId && + shouldLogIdFieldRangeWarning(properties[idField]) + ) { + logManager.logger.debug( + `Unique-identifier ("${idField}") has a value (${properties[idField]}) that is not a valid integer range (0 to ${Number.MAX_SAFE_INTEGER}); this may cause problems in some clients.`, + ); } return transformProperties(properties, dateFields); }; -function injectObjectId (feature) { +function injectObjectId(feature) { const { properties, geometry } = feature; const OBJECTID = createIntegerHash(JSON.stringify({ properties, geometry })); return { ...properties, - OBJECTID + OBJECTID, }; } -function shouldLogIdFieldDataTypeWarning (idFieldValue) { +function shouldLogIdFieldDataTypeWarning(idFieldValue) { return idFieldValue && !Number.isInteger(idFieldValue); } -function shouldLogIdFieldRangeWarning (idFieldValue) { - return idFieldValue && (idFieldValue < 0 || idFieldValue > Number.MAX_SAFE_INTEGER); +function shouldLogIdFieldRangeWarning(idFieldValue) { + return ( + idFieldValue && (idFieldValue < 0 || idFieldValue > Number.MAX_SAFE_INTEGER) + ); } -function transformProperties (properties, dateFields) { - return Object.entries(properties).reduce((transformedProperties, [key, value]) => { - if (dateFields.includes(key)) { - transformedProperties[key] = value === null ? null : new Date(value).getTime(); - } else if (_.isObject(value)) { - transformedProperties[key] = JSON.stringify(value); - } else { - transformedProperties[key] = value; - } - return transformedProperties; - }, {}); +function transformProperties(properties, dateFields) { + return Object.entries(properties).reduce( + (transformedProperties, [key, value]) => { + if (dateFields.includes(key)) { + transformedProperties[key] = + value === null ? null : new Date(value).getTime(); + } else if (_.isObject(value)) { + transformedProperties[key] = JSON.stringify(value); + } else { + transformedProperties[key] = value; + } + return transformedProperties; + }, + {}, + ); } diff --git a/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.js b/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.js index 043f5b886..499ecb6c7 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.js @@ -1,7 +1,7 @@ const _ = require('lodash'); const { geojsonToArcGIS } = require('@terraformer/arcgis'); -module.exports = function convert (geometry = {}) { +module.exports = function convert(geometry = {}) { if (!geometry || !geometry.type) return null; const result = geojsonToArcGIS(_.clone(geometry)); diff --git a/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.spec.js b/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.spec.js index 17b4afbea..3d7282238 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.spec.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-esri-geometry.spec.js @@ -23,10 +23,7 @@ test('toEsriGeometry: point', (t) => { t.plan(1); const transformed = toEsriGeometry({ type: 'Point', - coordinates: [ - 100, - 0 - ] + coordinates: [100, 0], }); t.deepEquals(transformed, { x: 100, y: 0 }); }); diff --git a/packages/winnow/src/filter-and-transform/transforms/to-geohash.js b/packages/winnow/src/filter-and-transform/transforms/to-geohash.js index 0bfee9500..6bed5e512 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-geohash.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-geohash.js @@ -1,7 +1,7 @@ const { encode } = require('ngeohash'); const { default: centroid } = require('@turf/centroid'); -function transformToGeohash (geometry = {}, precision = 8) { +function transformToGeohash(geometry = {}, precision = 8) { const { type, coordinates } = geometry; if (!type || !coordinates) return; diff --git a/packages/winnow/src/filter-and-transform/transforms/to-geohash.spec.js b/packages/winnow/src/filter-and-transform/transforms/to-geohash.spec.js index 366ec2644..38904b428 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-geohash.spec.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-geohash.spec.js @@ -4,40 +4,44 @@ const proxyquire = require('proxyquire'); const toGeohash = require('./to-geohash'); const modulePath = './to-geohash'; -test('toGeohash, empty input, returns undefined', t => { +test('toGeohash, empty input, returns undefined', (t) => { const result = toGeohash(); t.equals(result, undefined); t.end(); }); -test('toGeohash, empty geometry object, returns undefined', t => { +test('toGeohash, empty geometry object, returns undefined', (t) => { const result = toGeohash(); t.equals(result, undefined); t.end(); }); -test('project, missing input geometry coordinates, return input geometry', t => { +test('project, missing input geometry coordinates, return input geometry', (t) => { const result = toGeohash({ type: 'Point' }); t.deepEquals(result, undefined); t.end(); }); -test('project, missing input geometry type, return input geometry', t => { +test('project, missing input geometry type, return input geometry', (t) => { const result = toGeohash({ coordinates: [] }); t.deepEquals(result, undefined); t.end(); }); -test('toGeohash, point input, returns geohash', t => { - const geohashSpy = sinon.spy(function () { return 'geohash-result'; }); - const centroidSpy = sinon.spy(function () { return { coordinates: [11, 19] }; }); +test('toGeohash, point input, returns geohash', (t) => { + const geohashSpy = sinon.spy(function () { + return 'geohash-result'; + }); + const centroidSpy = sinon.spy(function () { + return { coordinates: [11, 19] }; + }); const toGeohash = proxyquire(modulePath, { - 'ngeohash': { // eslint-disable-line - encode: geohashSpy + ngeohash: { + encode: geohashSpy, }, '@turf/centroid': { - default: centroidSpy - } + default: centroidSpy, + }, }); const result = toGeohash({ type: 'Point', coordinates: [23, 24] }); t.equals(result, 'geohash-result'); @@ -47,36 +51,49 @@ test('toGeohash, point input, returns geohash', t => { t.end(); }); -test('toGeohash, non-point input, returns geohash', t => { - const geohashSpy = sinon.spy(function () { return 'geohash-result'; }); - const centroidSpy = sinon.spy(function () { return { coordinates: [11, 19] }; }); +test('toGeohash, non-point input, returns geohash', (t) => { + const geohashSpy = sinon.spy(function () { + return 'geohash-result'; + }); + const centroidSpy = sinon.spy(function () { + return { coordinates: [11, 19] }; + }); const toGeohash = proxyquire(modulePath, { - 'ngeohash': { // eslint-disable-line - encode: geohashSpy + ngeohash: { + encode: geohashSpy, }, '@turf/centroid': { - default: centroidSpy - } + default: centroidSpy, + }, + }); + const result = toGeohash({ + type: 'Polygon', + coordinates: 'polygon-coordinates', }); - const result = toGeohash({ type: 'Polygon', coordinates: 'polygon-coordinates' }); t.equals(result, 'geohash-result'); t.ok(geohashSpy.calledOnce); t.deepEquals(geohashSpy.firstCall.args, [19, 11, 8]); t.ok(centroidSpy.calledOnce); - t.deepEquals(centroidSpy.firstCall.args, [{ type: 'Polygon', coordinates: 'polygon-coordinates' }]); + t.deepEquals(centroidSpy.firstCall.args, [ + { type: 'Polygon', coordinates: 'polygon-coordinates' }, + ]); t.end(); }); -test('toGeohash, point input, precision input, returns geohash', t => { - const geohashSpy = sinon.spy(function () { return 'geohash-result'; }); - const centroidSpy = sinon.spy(function () { return { coordinates: [11, 19] }; }); +test('toGeohash, point input, precision input, returns geohash', (t) => { + const geohashSpy = sinon.spy(function () { + return 'geohash-result'; + }); + const centroidSpy = sinon.spy(function () { + return { coordinates: [11, 19] }; + }); const toGeohash = proxyquire(modulePath, { - 'ngeohash': { // eslint-disable-line - encode: geohashSpy + ngeohash: { + encode: geohashSpy, }, '@turf/centroid': { - default: centroidSpy - } + default: centroidSpy, + }, }); const result = toGeohash({ type: 'Point', coordinates: [23, 24] }, 5); t.equals(result, 'geohash-result'); diff --git a/packages/winnow/src/filter-and-transform/transforms/to-hash.js b/packages/winnow/src/filter-and-transform/transforms/to-hash.js index 8dac578d0..a5e92e652 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-hash.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-hash.js @@ -1,4 +1,4 @@ -function toHash (value, hashStore = {}) { +function toHash(value, hashStore = {}) { if (hashStore[value]) hashStore[value]++; else hashStore[value] = 1; return hashStore; diff --git a/packages/winnow/src/filter-and-transform/transforms/to-hash.spec.js b/packages/winnow/src/filter-and-transform/transforms/to-hash.spec.js index 96c2ef10c..e604be1fd 100644 --- a/packages/winnow/src/filter-and-transform/transforms/to-hash.spec.js +++ b/packages/winnow/src/filter-and-transform/transforms/to-hash.spec.js @@ -1,19 +1,19 @@ const test = require('tape'); const toHash = require('./to-hash'); -test('transformToHash, empty hashStore', spec => { +test('transformToHash, empty hashStore', (spec) => { const result = toHash('foobar'); spec.deepEquals(result, { foobar: 1 }); spec.end(); }); -test('transformToHash, initial count', spec => { +test('transformToHash, initial count', (spec) => { const result = toHash('foobar', { hello: 1 }); spec.deepEquals(result, { foobar: 1, hello: 1 }); spec.end(); }); -test('transformToHash, subsequent count', spec => { +test('transformToHash, subsequent count', (spec) => { const result = toHash('foobar', { foobar: 1, hello: 1 }); spec.deepEquals(result, { foobar: 2, hello: 1 }); spec.end(); diff --git a/packages/winnow/src/helpers/project-coordinates.js b/packages/winnow/src/helpers/project-coordinates.js index 8f386d2b4..be6198596 100644 --- a/packages/winnow/src/helpers/project-coordinates.js +++ b/packages/winnow/src/helpers/project-coordinates.js @@ -2,15 +2,19 @@ const proj4 = require('proj4'); const _ = require('lodash'); const transformCoordinates = require('./transform-coordinates'); -module.exports = function projectCoordinates (params) { +module.exports = function projectCoordinates(params) { const { coordinates, fromSR = 'EPSG:4326', toSR } = params; if (!toSR || fromSR === toSR) return coordinates; - return transformCoordinates(coordinates, { fromSR, toSR }, (coordinates, options) => { - if (_.isNumber(coordinates[0]) && _.isNumber(coordinates[1])) { - return proj4(options.fromSR, options.toSR, coordinates); - } - return coordinates; - }); + return transformCoordinates( + coordinates, + { fromSR, toSR }, + (coordinates, options) => { + if (_.isNumber(coordinates[0]) && _.isNumber(coordinates[1])) { + return proj4(options.fromSR, options.toSR, coordinates); + } + return coordinates; + }, + ); }; diff --git a/packages/winnow/src/helpers/project-coordinates.spec.js b/packages/winnow/src/helpers/project-coordinates.spec.js index 6d4fe8ba9..cd3b96c82 100644 --- a/packages/winnow/src/helpers/project-coordinates.spec.js +++ b/packages/winnow/src/helpers/project-coordinates.spec.js @@ -1,44 +1,51 @@ const test = require('tape'); const projectCoordinates = require('./project-coordinates'); -test('Do not project coordinates if one is null', t => { +test('Do not project coordinates if one is null', (t) => { t.plan(2); const transformed = projectCoordinates({ coordinates: [null, 63] }); t.equal(transformed[0], null, 'not projected'); t.equal(transformed[1], 63, 'not projected'); }); -test('Do not project coordinates if both are null', t => { +test('Do not project coordinates if both are null', (t) => { t.plan(2); const transformed = projectCoordinates({ coordinates: [null, null] }); t.equal(transformed[0], null, 'not projected'); t.equal(transformed[1], null, 'not projected'); }); -test('Do not project coordinates if empty array', t => { +test('Do not project coordinates if empty array', (t) => { t.plan(2); const transformed = projectCoordinates({ coordinates: [] }); t.equal(transformed[0], undefined, 'not projected'); t.equal(transformed[1], undefined, 'not projected'); }); -test('Do not project coordinates if no toSR', t => { +test('Do not project coordinates if no toSR', (t) => { t.plan(2); const transformed = projectCoordinates({ coordinates: [45, 75] }); t.equal(transformed[0], 45, 'not projected'); t.equal(transformed[1], 75, 'not projected'); }); -test('Project coordinates correctly', t => { +test('Project coordinates correctly', (t) => { t.plan(2); - const transformed = projectCoordinates({ coordinates: [45, 75], toSR: 'EPSG:3857' }); + const transformed = projectCoordinates({ + coordinates: [45, 75], + toSR: 'EPSG:3857', + }); t.equal(transformed[0], 5009377.085697311, 'projected correctly'); t.equal(transformed[1], 12932243.111992031, 'projected correctly'); }); -test('Do not project coordinates if target and source spatial reference are the same', t => { +test('Do not project coordinates if target and source spatial reference are the same', (t) => { t.plan(2); - const transformed = projectCoordinates({ coordinates: [45, 75], fromSR: 'EPSG:4326', toSR: 'EPSG:4326' }); + const transformed = projectCoordinates({ + coordinates: [45, 75], + fromSR: 'EPSG:4326', + toSR: 'EPSG:4326', + }); t.equal(transformed[0], 45, 'projected correctly'); t.equal(transformed[1], 75, 'projected correctly'); }); diff --git a/packages/winnow/src/helpers/transform-coordinates.js b/packages/winnow/src/helpers/transform-coordinates.js index d03d2ed2e..05a13dfc1 100644 --- a/packages/winnow/src/helpers/transform-coordinates.js +++ b/packages/winnow/src/helpers/transform-coordinates.js @@ -1,6 +1,10 @@ -module.exports = function transformCoordinates (coordinates, options = {}, transformFunction) { +module.exports = function transformCoordinates( + coordinates, + options = {}, + transformFunction, +) { if (Array.isArray(coordinates[0])) { - return coordinates.map(el => { + return coordinates.map((el) => { return transformCoordinates(el, options, transformFunction); }); } diff --git a/packages/winnow/src/helpers/transform-coordinates.spec.js b/packages/winnow/src/helpers/transform-coordinates.spec.js index bd412773e..cf8aa3ed4 100644 --- a/packages/winnow/src/helpers/transform-coordinates.spec.js +++ b/packages/winnow/src/helpers/transform-coordinates.spec.js @@ -1,7 +1,7 @@ const test = require('tape'); const transformCoordinates = require('./transform-coordinates'); -test('transform coordinates, point', t => { +test('transform coordinates, point', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -12,7 +12,7 @@ test('transform coordinates, point', t => { t.deepEquals(input, ['x', 'y']); }); -test('transform coordinates, line', t => { +test('transform coordinates, line', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -20,13 +20,16 @@ test('transform coordinates, line', t => { }; const input = [ [100.0, 0.0], - [101.0, 1.0] + [101.0, 1.0], ]; transformCoordinates(input, {}, transform); - t.deepEquals(input, [['x', 'y'], ['x', 'y']]); + t.deepEquals(input, [ + ['x', 'y'], + ['x', 'y'], + ]); }); -test('transform coordinates, polygon', t => { +test('transform coordinates, polygon', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -38,8 +41,8 @@ test('transform coordinates, polygon', t => { [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], - [100.0, 0.0] - ] + [100.0, 0.0], + ], ]; transformCoordinates(input, {}, transform); t.deepEquals(input, [ @@ -48,12 +51,12 @@ test('transform coordinates, polygon', t => { ['x', 'y'], ['x', 'y'], ['x', 'y'], - ['x', 'y'] - ] + ['x', 'y'], + ], ]); }); -test('transform coordinates, multi-point', t => { +test('transform coordinates, multi-point', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -61,14 +64,16 @@ test('transform coordinates, multi-point', t => { }; const input = [ [100.0, 0.0], - [101.0, 1.0] + [101.0, 1.0], ]; transformCoordinates(input, {}, transform); - t.deepEquals(input, [['x', 'y'], ['x', 'y']] - ); + t.deepEquals(input, [ + ['x', 'y'], + ['x', 'y'], + ]); }); -test('transform coordinates, multi-linestring', t => { +test('transform coordinates, multi-linestring', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -77,27 +82,27 @@ test('transform coordinates, multi-linestring', t => { const input = [ [ [100.0, 0.0], - [101.0, 1.0] + [101.0, 1.0], ], [ [102.0, 2.0], - [103.0, 3.0] - ] + [103.0, 3.0], + ], ]; transformCoordinates(input, {}, transform); t.deepEquals(input, [ [ ['x', 'y'], - ['x', 'y'] + ['x', 'y'], ], [ ['x', 'y'], - ['x', 'y'] - ] + ['x', 'y'], + ], ]); }); -test('transform coordinates, multi-polygon', t => { +test('transform coordinates, multi-polygon', (t) => { t.plan(1); const transform = (coordinates) => { coordinates[0] = 'x'; @@ -110,8 +115,8 @@ test('transform coordinates, multi-polygon', t => { [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], - [102.0, 2.0] - ] + [102.0, 2.0], + ], ], [ [ @@ -119,16 +124,16 @@ test('transform coordinates, multi-polygon', t => { [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], - [100.0, 0.0] + [100.0, 0.0], ], [ [100.2, 0.2], [100.2, 0.8], [100.8, 0.8], [100.8, 0.2], - [100.2, 0.2] - ] - ] + [100.2, 0.2], + ], + ], ]; transformCoordinates(input, {}, transform); t.deepEquals(input, [ @@ -138,8 +143,8 @@ test('transform coordinates, multi-polygon', t => { ['x', 'y'], ['x', 'y'], ['x', 'y'], - ['x', 'y'] - ] + ['x', 'y'], + ], ], [ [ @@ -147,15 +152,15 @@ test('transform coordinates, multi-polygon', t => { ['x', 'y'], ['x', 'y'], ['x', 'y'], - ['x', 'y'] + ['x', 'y'], ], [ ['x', 'y'], ['x', 'y'], ['x', 'y'], ['x', 'y'], - ['x', 'y'] - ] - ] + ['x', 'y'], + ], + ], ]); }); diff --git a/packages/winnow/src/index.js b/packages/winnow/src/index.js index 96eda04c3..354d0e44c 100644 --- a/packages/winnow/src/index.js +++ b/packages/winnow/src/index.js @@ -11,5 +11,5 @@ module.exports = { prepareQuery, querySql: filterAndTransform, prepareSql: prepareFilterAndTransform, - setLogger + setLogger, }; diff --git a/packages/winnow/src/log-manager.js b/packages/winnow/src/log-manager.js index 6b0308f39..28df83cdd 100644 --- a/packages/winnow/src/log-manager.js +++ b/packages/winnow/src/log-manager.js @@ -2,7 +2,7 @@ const Logger = require('@koopjs/logger'); let logger = new Logger(); module.exports = { - get logger () { + get logger() { return logger; }, setLogger: ({ logger: _logger, logLevel }) => { @@ -11,9 +11,9 @@ module.exports = { logger.silly('Winnow no longer using default logger.'); return; } - + if (logLevel) { logger = new Logger({ logLevel }); } - } + }, }; diff --git a/packages/winnow/src/normalize-query-options/aggregates.js b/packages/winnow/src/normalize-query-options/aggregates.js index 46b2dfa91..2b6cac612 100644 --- a/packages/winnow/src/normalize-query-options/aggregates.js +++ b/packages/winnow/src/normalize-query-options/aggregates.js @@ -1,4 +1,4 @@ -function normalizeAggregates ({ aggregates, outStatistics }) { +function normalizeAggregates({ aggregates, outStatistics }) { if (outStatistics) { const aggregates = getAggregatesFromOutStatistics(outStatistics); return normalizeAggregateNames(aggregates); @@ -9,24 +9,24 @@ function normalizeAggregates ({ aggregates, outStatistics }) { } } -function getAggregatesFromOutStatistics (outStatistics) { - return outStatistics.map(agg => { +function getAggregatesFromOutStatistics(outStatistics) { + return outStatistics.map((agg) => { return { type: agg.statisticType, field: agg.onStatisticField, - name: agg.outStatisticFieldName + name: agg.outStatisticFieldName, }; }); } -function normalizeAggregateNames (aggregates) { - return aggregates.map(aggregate => { +function normalizeAggregateNames(aggregates) { + return aggregates.map((aggregate) => { const { type, field } = aggregate; const name = aggregate.name ? aggregate.name : `${type}_${field}`; return { name: name.replace(/\s/g, '_'), type, - field + field, }; }); } diff --git a/packages/winnow/src/normalize-query-options/aggregates.spec.js b/packages/winnow/src/normalize-query-options/aggregates.spec.js index 67216b21d..ea5a18759 100644 --- a/packages/winnow/src/normalize-query-options/aggregates.spec.js +++ b/packages/winnow/src/normalize-query-options/aggregates.spec.js @@ -1,60 +1,66 @@ const test = require('tape'); const normalizeAggregates = require('./aggregates'); -test('normalize-options, aggregates: undefined', t => { +test('normalize-options, aggregates: undefined', (t) => { t.plan(1); - const normalized = normalizeAggregates({ }); + const normalized = normalizeAggregates({}); t.equal(normalized, undefined); }); -test('normalize-options, aggregates: generate name property when missing', t => { +test('normalize-options, aggregates: generate name property when missing', (t) => { t.plan(1); const options = { aggregates: [ { type: 'avg', - field: 'height' - } - ] + field: 'height', + }, + ], }; const normalized = normalizeAggregates(options); - t.deepEquals(normalized, [{ type: 'avg', field: 'height', name: 'avg_height' }]); + t.deepEquals(normalized, [ + { type: 'avg', field: 'height', name: 'avg_height' }, + ]); }); -test('normalize-options, aggregates: remove blank space in name property', t => { +test('normalize-options, aggregates: remove blank space in name property', (t) => { t.plan(1); const options = { aggregates: [ { type: 'avg', - field: 'tree height' - } - ] + field: 'tree height', + }, + ], }; const normalized = normalizeAggregates(options); - t.deepEquals(normalized, [{ type: 'avg', field: 'tree height', name: 'avg_tree_height' }]); + t.deepEquals(normalized, [ + { type: 'avg', field: 'tree height', name: 'avg_tree_height' }, + ]); }); -test('normalize-options, aggregates: defer to outStatistics as aggregates source', t => { +test('normalize-options, aggregates: defer to outStatistics as aggregates source', (t) => { t.plan(1); const options = { aggregates: [ { type: 'avg', - field: 'height' - } + field: 'height', + }, ], outStatistics: [ { statisticType: 'avg', - onStatisticField: 'Trunk_Diameter' - } - ] + onStatisticField: 'Trunk_Diameter', + }, + ], }; const normalized = normalizeAggregates(options); - t.deepEquals(normalized, [{ type: 'avg', field: 'Trunk_Diameter', name: 'avg_Trunk_Diameter' }]); + t.deepEquals(normalized, [ + { type: 'avg', field: 'Trunk_Diameter', name: 'avg_Trunk_Diameter' }, + ]); }); diff --git a/packages/winnow/src/normalize-query-options/classification.spec.js b/packages/winnow/src/normalize-query-options/classification.spec.js index 0e10b5e32..594266a87 100644 --- a/packages/winnow/src/normalize-query-options/classification.spec.js +++ b/packages/winnow/src/normalize-query-options/classification.spec.js @@ -1,19 +1,21 @@ const test = require('tape'); const normalizeClassification = require('./classification'); -test('normalize-options, classification: undefined', t => { +test('normalize-options, classification: undefined', (t) => { t.plan(1); - const normalized = normalizeClassification({ }); + const normalized = normalizeClassification({}); t.equal(normalized, undefined); }); -test('normalize-options, classification: return classification', t => { +test('normalize-options, classification: return classification', (t) => { t.plan(1); - const normalized = normalizeClassification({ classification: 'some classification' }); + const normalized = normalizeClassification({ + classification: 'some classification', + }); t.equal(normalized, 'some classification'); }); -test('normalize-options, classification: classificationDef without type should throw error', t => { +test('normalize-options, classification: classificationDef without type should throw error', (t) => { t.plan(1); try { normalizeClassification({ classificationDef: {} }); @@ -22,7 +24,7 @@ test('normalize-options, classification: classificationDef without type should t } }); -test('normalize-options, classification: classificationDef of type "classBreaksDef"', t => { +test('normalize-options, classification: classificationDef of type "classBreaksDef"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -32,8 +34,8 @@ test('normalize-options, classification: classificationDef of type "classBreaksD standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByField', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -42,11 +44,11 @@ test('normalize-options, classification: classificationDef of type "classBreaksD stddev_intv: 10, breakCount: 99, normType: 'field', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: classificationMethod "esriClassifyNaturalBreaks"', t => { +test('normalize-options, classification: classificationMethod "esriClassifyNaturalBreaks"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -56,8 +58,8 @@ test('normalize-options, classification: classificationMethod "esriClassifyNatur standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByField', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -66,11 +68,11 @@ test('normalize-options, classification: classificationMethod "esriClassifyNatur stddev_intv: 10, breakCount: 99, normType: 'field', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: classificationMethod "esriClassifyQuantile"', t => { +test('normalize-options, classification: classificationMethod "esriClassifyQuantile"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -80,8 +82,8 @@ test('normalize-options, classification: classificationMethod "esriClassifyQuant standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByField', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -90,11 +92,11 @@ test('normalize-options, classification: classificationMethod "esriClassifyQuant stddev_intv: 10, breakCount: 99, normType: 'field', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: classificationMethod "esriClassifyGeometricalInterval"', t => { +test('normalize-options, classification: classificationMethod "esriClassifyGeometricalInterval"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -104,8 +106,8 @@ test('normalize-options, classification: classificationMethod "esriClassifyGeome standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByField', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -114,11 +116,11 @@ test('normalize-options, classification: classificationMethod "esriClassifyGeome stddev_intv: 10, breakCount: 99, normType: 'field', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: classificationMethod "esriClassifyStandardDeviation"', t => { +test('normalize-options, classification: classificationMethod "esriClassifyStandardDeviation"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -128,8 +130,8 @@ test('normalize-options, classification: classificationMethod "esriClassifyStand standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByField', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -138,11 +140,11 @@ test('normalize-options, classification: classificationMethod "esriClassifyStand stddev_intv: 10, breakCount: 99, normType: 'field', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: transformationMethod "esriNormalizeByLog"', t => { +test('normalize-options, classification: transformationMethod "esriNormalizeByLog"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -152,8 +154,8 @@ test('normalize-options, classification: transformationMethod "esriNormalizeByLo standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByLog', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -162,11 +164,11 @@ test('normalize-options, classification: transformationMethod "esriNormalizeByLo stddev_intv: 10, breakCount: 99, normType: 'log', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: transformationMethod "esriNormalizeByPercentOfTotal"', t => { +test('normalize-options, classification: transformationMethod "esriNormalizeByPercentOfTotal"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { @@ -176,8 +178,8 @@ test('normalize-options, classification: transformationMethod "esriNormalizeByPe standardDeviationInterval: 10, breakCount: 99, normalizationType: 'esriNormalizeByPercentOfTotal', - normalizationField: 'def' - } + normalizationField: 'def', + }, }); t.deepEquals(normalized, { type: 'classes', @@ -186,20 +188,20 @@ test('normalize-options, classification: transformationMethod "esriNormalizeByPe stddev_intv: 10, breakCount: 99, normType: 'percent', - normField: 'def' + normField: 'def', }); }); -test('normalize-options, classification: classificationDef of type "uniqueValueDev"', t => { +test('normalize-options, classification: classificationDef of type "uniqueValueDev"', (t) => { t.plan(1); const normalized = normalizeClassification({ classificationDef: { type: 'uniqueValueDef', - uniqueValueFields: ['abc', 'def'] - } + uniqueValueFields: ['abc', 'def'], + }, }); t.deepEquals(normalized, { type: 'unique', - fields: ['abc', 'def'] + fields: ['abc', 'def'], }); }); diff --git a/packages/winnow/src/normalize-query-options/collection.js b/packages/winnow/src/normalize-query-options/collection.js index 46eeec572..232037345 100644 --- a/packages/winnow/src/normalize-query-options/collection.js +++ b/packages/winnow/src/normalize-query-options/collection.js @@ -1,7 +1,7 @@ const _ = require('lodash'); const { detectEsriFieldType } = require('./helpers'); -function normalizeCollection (collection, features) { +function normalizeCollection(collection, features) { if (!collection) return; const clonedCollection = _.cloneDeep(collection); @@ -18,14 +18,14 @@ function normalizeCollection (collection, features) { return clonedCollection; } -function getFieldsFromFeature (feature) { +function getFieldsFromFeature(feature) { if (!feature) return; const { properties = {} } = feature; - return Object.keys(properties).map(key => { + return Object.keys(properties).map((key) => { return { name: key, - type: detectEsriFieldType(properties[key]) + type: detectEsriFieldType(properties[key]), }; }); } diff --git a/packages/winnow/src/normalize-query-options/collection.spec.js b/packages/winnow/src/normalize-query-options/collection.spec.js index 9d0c17b17..5824b333b 100644 --- a/packages/winnow/src/normalize-query-options/collection.spec.js +++ b/packages/winnow/src/normalize-query-options/collection.spec.js @@ -1,42 +1,43 @@ - const test = require('tape'); const normalizeCollection = require('./collection'); -test('normalize-options, collection: undefined', t => { +test('normalize-options, collection: undefined', (t) => { t.plan(1); const normalized = normalizeCollection(); t.equal(normalized, undefined); }); -test('normalize-options, collection: add metadata object', t => { +test('normalize-options, collection: add metadata object', (t) => { t.plan(1); - const normalized = normalizeCollection({ }); + const normalized = normalizeCollection({}); t.deepEquals(normalized, { metadata: {} }); }); -test('normalize-options, collection: unable to generate metadata fields without feature', t => { +test('normalize-options, collection: unable to generate metadata fields without feature', (t) => { t.plan(1); - const normalized = normalizeCollection({ }, []); + const normalized = normalizeCollection({}, []); t.deepEquals(normalized, { metadata: {} }); }); -test('normalize-options, collection: metadata.fields already defined', t => { +test('normalize-options, collection: metadata.fields already defined', (t) => { t.plan(1); const normalized = normalizeCollection({ metadata: { fields: ['abc'] } }); t.deepEquals(normalized, { metadata: { fields: ['abc'] } }); }); -test('normalize-options, collection: generate metadata fields from feature', t => { +test('normalize-options, collection: generate metadata fields from feature', (t) => { t.plan(1); - const normalized = normalizeCollection({ }, [{ properties: { name: 'test' } }]); + const normalized = normalizeCollection({}, [ + { properties: { name: 'test' } }, + ]); t.deepEquals(normalized, { metadata: { fields: [ { name: 'name', - type: 'String' - } - ] - } + type: 'String', + }, + ], + }, }); }); diff --git a/packages/winnow/src/normalize-query-options/date-fields.js b/packages/winnow/src/normalize-query-options/date-fields.js index c41e83531..87043d4a0 100644 --- a/packages/winnow/src/normalize-query-options/date-fields.js +++ b/packages/winnow/src/normalize-query-options/date-fields.js @@ -3,14 +3,19 @@ const _ = require('lodash'); * @param {object} collection - the GeoJSON object from Koop (with features omitted) * @param {*} requestedFields */ -function deriveDateFields (collection, requestedFields) { +function deriveDateFields(collection, requestedFields) { if (!_.get(collection, 'metadata.fields')) return []; - return collection.metadata.fields.filter(({ type, name }) => { - return type === 'Date' && (requestedFields === undefined || requestedFields.indexOf(name) > -1); - }).map(({ name }) => { - return name; - }); + return collection.metadata.fields + .filter(({ type, name }) => { + return ( + type === 'Date' && + (requestedFields === undefined || requestedFields.indexOf(name) > -1) + ); + }) + .map(({ name }) => { + return name; + }); } module.exports = deriveDateFields; diff --git a/packages/winnow/src/normalize-query-options/date-fields.spec.js b/packages/winnow/src/normalize-query-options/date-fields.spec.js index 090fb0c5c..1bc9c30ad 100644 --- a/packages/winnow/src/normalize-query-options/date-fields.spec.js +++ b/packages/winnow/src/normalize-query-options/date-fields.spec.js @@ -1,52 +1,55 @@ const test = require('tape'); const getDateFields = require('./date-fields'); -test('normalize-query-options, date-fields: undefined metadata', t => { +test('normalize-query-options, date-fields: undefined metadata', (t) => { t.plan(1); const normalized = getDateFields(); t.deepEquals(normalized, []); }); -test('normalize-query-options, date-fields: undefined metadata.fields', t => { +test('normalize-query-options, date-fields: undefined metadata.fields', (t) => { t.plan(1); const normalized = getDateFields({}); t.deepEquals(normalized, []); }); -test('normalize-query-options, date-fields: metadata.fields are empty array', t => { +test('normalize-query-options, date-fields: metadata.fields are empty array', (t) => { t.plan(1); const normalized = getDateFields({ fields: [] }); t.deepEquals(normalized, []); }); -test('normalize-query-options, date-fields: requestedFields undefined', t => { +test('normalize-query-options, date-fields: requestedFields undefined', (t) => { t.plan(1); const normalized = getDateFields({ metadata: { fields: [ { name: 'hello', type: 'Date' }, - { name: 'world', type: 'String' } - ] - } + { name: 'world', type: 'String' }, + ], + }, }); t.deepEquals(normalized, ['hello']); }); -test('normalize-query-options, date-fields: requestedFields defined', t => { +test('normalize-query-options, date-fields: requestedFields defined', (t) => { t.plan(1); - const normalized = getDateFields({ - metadata: { - fields: [ - { name: 'hello', type: 'Date' }, - { name: 'world', type: 'String' }, - { name: 'foo', type: 'String' } - ] - } - }, ['hello', 'foo']); + const normalized = getDateFields( + { + metadata: { + fields: [ + { name: 'hello', type: 'Date' }, + { name: 'world', type: 'String' }, + { name: 'foo', type: 'String' }, + ], + }, + }, + ['hello', 'foo'], + ); t.deepEquals(normalized, ['hello']); }); diff --git a/packages/winnow/src/normalize-query-options/fields.js b/packages/winnow/src/normalize-query-options/fields.js index 504d5a63e..9dd07d782 100644 --- a/packages/winnow/src/normalize-query-options/fields.js +++ b/packages/winnow/src/normalize-query-options/fields.js @@ -4,7 +4,7 @@ const { normalizeArray } = require('./helpers'); * Normalize the fields option * @param {Object} options */ -function normalizeFields (options) { +function normalizeFields(options) { const { returnIdsOnly, outFields, collection } = options; const idField = _.get(collection, 'metadata.idField'); // returnIdsOnly overrules all other fields options values diff --git a/packages/winnow/src/normalize-query-options/fields.spec.js b/packages/winnow/src/normalize-query-options/fields.spec.js index 7a2aa51db..9bf5c5cce 100644 --- a/packages/winnow/src/normalize-query-options/fields.spec.js +++ b/packages/winnow/src/normalize-query-options/fields.spec.js @@ -1,69 +1,72 @@ const test = require('tape'); const normalizeFields = require('./fields'); -test('normalize-options, fields: undefined', t => { +test('normalize-options, fields: undefined', (t) => { t.plan(1); - const normalized = normalizeFields({ }); + const normalized = normalizeFields({}); t.equal(normalized, undefined); }); -test('normalize-options, fields: defer to "fields" value', t => { +test('normalize-options, fields: defer to "fields" value', (t) => { t.plan(1); - const normalizedFields = normalizeFields({ fields: 'hello', outFields: 'world' }); + const normalizedFields = normalizeFields({ + fields: 'hello', + outFields: 'world', + }); t.deepEquals(normalizedFields, ['hello']); }); -test('normalize-options, fields: remove Geoservices-style "*" when present', t => { +test('normalize-options, fields: remove Geoservices-style "*" when present', (t) => { t.plan(1); const normalizedFields = normalizeFields({ fields: '*' }); t.deepEquals(normalizedFields, undefined); }); -test('normalize-options, fields: convert string to array', t => { +test('normalize-options, fields: convert string to array', (t) => { t.plan(1); const normalizedFields = normalizeFields({ fields: 'hello,world' }); t.deepEquals(normalizedFields, ['hello', 'world']); }); -test('normalize-options, fields: convert string to array, trim whitespace', t => { +test('normalize-options, fields: convert string to array, trim whitespace', (t) => { t.plan(1); const normalizedFields = normalizeFields({ fields: 'hello ,world' }); t.deepEquals(normalizedFields, ['hello', 'world']); }); -test('normalize-options, fields: value is a string array', t => { +test('normalize-options, fields: value is a string array', (t) => { t.plan(2); const options = { - fields: ['test', 'field', 'names'] + fields: ['test', 'field', 'names'], }; const fields = normalizeFields(options); t.ok(Array.isArray(fields)); t.deepEquals(fields, ['test', 'field', 'names']); }); -test('normalize-options, fields: returnIdsOnly is set to true and an idField is set', t => { +test('normalize-options, fields: returnIdsOnly is set to true and an idField is set', (t) => { t.plan(1); const options = { returnIdsOnly: true, outFields: '*', collection: { metadata: { - idField: 'feature_id' - } - } + idField: 'feature_id', + }, + }, }; const fields = normalizeFields(options); t.deepEquals(fields, ['feature_id']); }); -test('normalize-options, fields: returnIdsOnly is set to true and an idField is not set', t => { +test('normalize-options, fields: returnIdsOnly is set to true and an idField is not set', (t) => { t.plan(1); const options = { returnIdsOnly: true, - outFields: '*' + outFields: '*', }; const fields = normalizeFields(options); t.deepEquals(fields, ['OBJECTID']); diff --git a/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.js b/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.js index 82476a3d6..89c70c4ec 100644 --- a/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.js +++ b/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.js @@ -9,19 +9,24 @@ const normalizeSpatialReference = require('./spatial-reference'); * @param {object} options options object that may or may not have "geometry" and "inSR" properties * @returns {string} EPSG: or srs WKT; defaults to EPSG:4326 */ -function normalizeGeometryFilterSpatialReference (options = {}) { +function normalizeGeometryFilterSpatialReference(options = {}) { const geometry = options.geometry || options.bbox; - const geometryEnvelopeSpatialReference = extractGeometryFilterSpatialReference(geometry); + const geometryEnvelopeSpatialReference = + extractGeometryFilterSpatialReference(geometry); - const spatialReference = normalizeSpatialReference(geometryEnvelopeSpatialReference || options.inSR); + const spatialReference = normalizeSpatialReference( + geometryEnvelopeSpatialReference || options.inSR, + ); if (!spatialReference) { - logManager.logger.debug('geometry filter spatial reference unknown. Defaulting to EPSG:4326.'); + logManager.logger.debug( + 'geometry filter spatial reference unknown. Defaulting to EPSG:4326.', + ); } return spatialReference || { wkid: 4326 }; } -function extractGeometryFilterSpatialReference (geometry) { +function extractGeometryFilterSpatialReference(geometry) { if (!geometry) return; if (_.isString(geometry) || _.isArray(geometry)) { diff --git a/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.spec.js b/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.spec.js index a65d7e69a..a71653608 100644 --- a/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.spec.js +++ b/packages/winnow/src/normalize-query-options/geometry-filter-spatial-reference.spec.js @@ -1,71 +1,71 @@ const test = require('tape'); const normalizeGeometryFilterSpatialReference = require('./geometry-filter-spatial-reference'); -test('normalize-query-options, geometry-filter-spatial-reference: undefined input', t => { +test('normalize-query-options, geometry-filter-spatial-reference: undefined input', (t) => { t.plan(1); const { wkid } = normalizeGeometryFilterSpatialReference(); t.equal(wkid, 4326); }); -test('normalize-query-options, geometry-filter-spatial-reference: undefined options', t => { +test('normalize-query-options, geometry-filter-spatial-reference: undefined options', (t) => { t.plan(1); const { wkid } = normalizeGeometryFilterSpatialReference({}); t.equal(wkid, 4326); }); -test('normalize-query-options, geometry-filter-spatial-reference: defer to geometry option', t => { +test('normalize-query-options, geometry-filter-spatial-reference: defer to geometry option', (t) => { t.plan(1); const options = { geometry: '100,200,300,400,3857', bbox: '100,200,300,400,4326', - inSR: '4269' + inSR: '4269', }; const { wkid } = normalizeGeometryFilterSpatialReference(options); t.equal(wkid, 3857); }); -test('normalize-query-options, geometry-filter-spatial-reference: defer to bbox option if no geometry', t => { +test('normalize-query-options, geometry-filter-spatial-reference: defer to bbox option if no geometry', (t) => { t.plan(1); const options = { bbox: '100,200,300,400,3857', - inSR: '4269' + inSR: '4269', }; const { wkid } = normalizeGeometryFilterSpatialReference(options); t.equal(wkid, 3857); }); -test('normalize-query-options, geometry-filter-spatial-reference: geometry filter bbox missing spatial reference', t => { +test('normalize-query-options, geometry-filter-spatial-reference: geometry filter bbox missing spatial reference', (t) => { t.plan(1); const options = { geometry: '100,200,300,400', - inSR: '4269' + inSR: '4269', }; const { wkid } = normalizeGeometryFilterSpatialReference(options); t.equal(wkid, 4269); }); -test('normalize-query-options, geometry-filter-spatial-reference: defer to geometry filter wkid', t => { +test('normalize-query-options, geometry-filter-spatial-reference: defer to geometry filter wkid', (t) => { t.plan(1); const options = { geometry: { spatialReference: { - wkid: 4326 - } + wkid: 4326, + }, }, - inSR: '4269' + inSR: '4269', }; const { wkid } = normalizeGeometryFilterSpatialReference(options); t.equal(wkid, 4326); }); -test('normalize-query-options, geometry-filter-spatial-reference: inSR string', t => { +test('normalize-query-options, geometry-filter-spatial-reference: inSR string', (t) => { t.plan(1); const options = { inSR: '4269' }; const { wkid } = normalizeGeometryFilterSpatialReference(options); t.equal(wkid, 4269); }); -test('normalize-query-options, geometry-filter-spatial-reference: inSR spatialReference object', t => { +test('normalize-query-options, geometry-filter-spatial-reference: inSR spatialReference object', (t) => { t.plan(1); const options = { inSR: { wkid: 4269 } }; const { wkid } = normalizeGeometryFilterSpatialReference(options); diff --git a/packages/winnow/src/normalize-query-options/geometry-filter.js b/packages/winnow/src/normalize-query-options/geometry-filter.js index 3310602b8..a3cd84f6c 100644 --- a/packages/winnow/src/normalize-query-options/geometry-filter.js +++ b/packages/winnow/src/normalize-query-options/geometry-filter.js @@ -6,12 +6,13 @@ const projectCoordinates = require('../helpers/project-coordinates'); const normalizeGeometryFilterSpatialReference = require('./geometry-filter-spatial-reference'); const normalizeSourceSR = require('./source-data-spatial-reference'); -function normalizeGeometryFilter (options = {}) { +function normalizeGeometryFilter(options = {}) { const geometry = options.geometry || options.bbox; if (!geometry) return; - const geometryFilterSpatialReference = normalizeGeometryFilterSpatialReference(options); + const geometryFilterSpatialReference = + normalizeGeometryFilterSpatialReference(options); const fromSR = getCrsString(geometryFilterSpatialReference); const geometryFilter = transformGeometryToGeojson(geometry); @@ -27,20 +28,20 @@ function normalizeGeometryFilter (options = {}) { geometryFilter.coordinates = projectCoordinates({ coordinates: geometryFilter.coordinates, fromSR, - toSR + toSR, }); return geometryFilter; } -function transformGeometryToGeojson (geometry) { +function transformGeometryToGeojson(geometry) { if (_.isString(geometry) || Array.isArray(geometry)) { const coordinates = normalizeArray(geometry); if (coordinates.length === 2) { return { type: 'Point', - coordinates: coordinates.map(Number) + coordinates: coordinates.map(Number), }; } @@ -58,20 +59,22 @@ function transformGeometryToGeojson (geometry) { return geometry; } -function transformEsriEnvelopeToPolygon ({ xmin, ymin, xmax, ymax }) { +function transformEsriEnvelopeToPolygon({ xmin, ymin, xmax, ymax }) { return { type: 'Polygon', - coordinates: [[ - [xmin, ymin], - [xmax, ymin], - [xmax, ymax], - [xmin, ymax], - [xmin, ymin] - ]] + coordinates: [ + [ + [xmin, ymin], + [xmax, ymin], + [xmax, ymax], + [xmin, ymax], + [xmin, ymin], + ], + ], }; } -function getCrsString ({ wkt, wkid } = {}) { +function getCrsString({ wkt, wkid } = {}) { return wkt || `EPSG:${wkid}`; } diff --git a/packages/winnow/src/normalize-query-options/geometry-filter.spec.js b/packages/winnow/src/normalize-query-options/geometry-filter.spec.js index cf0ab1eb8..6b86a4cf3 100644 --- a/packages/winnow/src/normalize-query-options/geometry-filter.spec.js +++ b/packages/winnow/src/normalize-query-options/geometry-filter.spec.js @@ -1,15 +1,18 @@ const test = require('tape'); const normalizeGeometryFilter = require('./geometry-filter'); -test('normalize-query-options, geometry-filter: undefined options input', t => { +test('normalize-query-options, geometry-filter: undefined options input', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter(); t.equal(geometryFilter, undefined); }); -test('normalize-query-options, geometry-filter: defer to geometry options', t => { +test('normalize-query-options, geometry-filter: defer to geometry options', (t) => { t.plan(1); - const geometryFilter = normalizeGeometryFilter({ geometry: [10, 15, 20, 25], bbox: [0, 45, 50, 90] }); + const geometryFilter = normalizeGeometryFilter({ + geometry: [10, 15, 20, 25], + bbox: [0, 45, 50, 90], + }); t.deepEquals(geometryFilter, { type: 'Polygon', coordinates: [ @@ -18,13 +21,13 @@ test('normalize-query-options, geometry-filter: defer to geometry options', t => [20, 15], [20, 25], [10, 25], - [10, 15] - ] - ] + [10, 15], + ], + ], }); }); -test('normalize-query-options, geometry-filter: use bbox if geometry is undefined', t => { +test('normalize-query-options, geometry-filter: use bbox if geometry is undefined', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ bbox: [0, 45, 50, 90] }); t.deepEquals(geometryFilter, { @@ -35,15 +38,18 @@ test('normalize-query-options, geometry-filter: use bbox if geometry is undefine [50, 45], [50, 90], [0, 90], - [0, 45] - ] - ] + [0, 45], + ], + ], }); }); -test('normalize-query-options, geometry-filter: filter spatial reference of 4326 does not trigger reproject', t => { +test('normalize-query-options, geometry-filter: filter spatial reference of 4326 does not trigger reproject', (t) => { t.plan(1); - const geometryFilter = normalizeGeometryFilter({ geometry: [0, 45, 50, 90], inSR: 4326 }); + const geometryFilter = normalizeGeometryFilter({ + geometry: [0, 45, 50, 90], + inSR: 4326, + }); t.deepEquals(geometryFilter, { type: 'Polygon', coordinates: [ @@ -52,24 +58,24 @@ test('normalize-query-options, geometry-filter: filter spatial reference of 4326 [50, 45], [50, 90], [0, 90], - [0, 45] - ] - ] + [0, 45], + ], + ], }); }); -test('normalize-query-options, geometry-filter: filter spatial reference of 3857 does trigger reproject', t => { +test('normalize-query-options, geometry-filter: filter spatial reference of 3857 does trigger reproject', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: { spatialReference: { - latestWkid: 3857 + latestWkid: 3857, }, xmin: 782715.169637017, ymin: 6569915.455168739, xmax: 787607.1394472681, - ymax: 6574807.42497899 - } + ymax: 6574807.42497899, + }, }); t.deepEquals(geometryFilter, { type: 'Polygon', @@ -79,25 +85,25 @@ test('normalize-query-options, geometry-filter: filter spatial reference of 3857 [7.0751953124713625, 50.708634400835436], [7.0751953124713625, 50.736455137017856], [7.031249999971363, 50.736455137017856], - [7.031249999971363, 50.708634400835436] - ] - ] + [7.031249999971363, 50.708634400835436], + ], + ], }); }); -test('normalize-query-options, geometry-filter: data spatial reference of 3857 triggers reproject of filter', t => { +test('normalize-query-options, geometry-filter: data spatial reference of 3857 triggers reproject of filter', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: { spatialReference: { - latestWkid: 4326 + latestWkid: 4326, }, xmin: 0, ymin: 10, xmax: 30, - ymax: 45 + ymax: 45, }, - sourceSR: 3857 + sourceSR: 3857, }); t.deepEquals(geometryFilter, { type: 'Polygon', @@ -107,25 +113,25 @@ test('normalize-query-options, geometry-filter: data spatial reference of 3857 t [3339584.723798207, 1118889.9748579597], [3339584.723798207, 5621521.486192066], [0, 5621521.486192066], - [0, 1118889.9748579597] - ] - ] + [0, 1118889.9748579597], + ], + ], }); }); -test('normalize-query-options, geometry-filter: same data/filter spatial reference skips filter reprojection', t => { +test('normalize-query-options, geometry-filter: same data/filter spatial reference skips filter reprojection', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: { spatialReference: { - latestWkid: 3857 + latestWkid: 3857, }, xmin: 782715.169637017, ymin: 6569915.455168739, xmax: 787607.1394472681, - ymax: 6574807.42497899 + ymax: 6574807.42497899, }, - sourceSR: 3857 + sourceSR: 3857, }); t.deepEquals(geometryFilter, { type: 'Polygon', @@ -135,13 +141,13 @@ test('normalize-query-options, geometry-filter: same data/filter spatial referen [787607.1394472681, 6569915.455168739], [787607.1394472681, 6574807.42497899], [782715.169637017, 6574807.42497899], - [782715.169637017, 6569915.455168739] - ] - ] + [782715.169637017, 6569915.455168739], + ], + ], }); }); -test('normalize-query-options, geometry-filter: geometry as coordinate string polygon', t => { +test('normalize-query-options, geometry-filter: geometry as coordinate string polygon', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: '10,15,20,25' }); t.deepEquals(geometryFilter, { @@ -152,24 +158,26 @@ test('normalize-query-options, geometry-filter: geometry as coordinate string po [20, 15], [20, 25], [10, 25], - [10, 15] - ] - ] + [10, 15], + ], + ], }); }); -test('normalize-query-options, geometry-filter: geometry as coordinate string point', t => { +test('normalize-query-options, geometry-filter: geometry as coordinate string point', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: '-10,10' }); t.deepEquals(geometryFilter, { type: 'Point', - coordinates: [-10, 10] + coordinates: [-10, 10], }); }); -test('normalize-query-options, geometry-filter: geometry as coordinate array polygon', t => { +test('normalize-query-options, geometry-filter: geometry as coordinate array polygon', (t) => { t.plan(1); - const geometryFilter = normalizeGeometryFilter({ geometry: [10, 15, 20, 25] }); + const geometryFilter = normalizeGeometryFilter({ + geometry: [10, 15, 20, 25], + }); t.deepEquals(geometryFilter, { type: 'Polygon', coordinates: [ @@ -178,22 +186,22 @@ test('normalize-query-options, geometry-filter: geometry as coordinate array pol [20, 15], [20, 25], [10, 25], - [10, 15] - ] - ] + [10, 15], + ], + ], }); }); -test('normalize-query-options, geometry-filter: geometry as coordinate array point', t => { +test('normalize-query-options, geometry-filter: geometry as coordinate array point', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: [-10, 10] }); t.deepEquals(geometryFilter, { type: 'Point', - coordinates: [-10, 10] + coordinates: [-10, 10], }); }); -test('normalize-query-options, geometry-filter: geometry as Esri envelope', t => { +test('normalize-query-options, geometry-filter: geometry as Esri envelope', (t) => { t.plan(1); const geometryFilter = normalizeGeometryFilter({ geometry: { @@ -208,10 +216,10 @@ test('normalize-query-options, geometry-filter: geometry as Esri envelope', t => [-119.86215200336552, 39.545849846100822], [-119.86214507417176, 39.545859427834422], [-119.86209313222116, 39.545931275663776], - [-119.86203847085071, 39.545907591418406] - ] - ] - } + [-119.86203847085071, 39.545907591418406], + ], + ], + }, }); t.deepEquals(geometryFilter, { type: 'Polygon', @@ -226,8 +234,8 @@ test('normalize-query-options, geometry-filter: geometry as Esri envelope', t => [-119.86210620156871, 39.5457670939942], [-119.86201962858273, 39.545886843071926], [-119.86204539539456, 39.54589800884157], - [-119.8620384708507, 39.545907591418406] - ] - ] + [-119.8620384708507, 39.545907591418406], + ], + ], }); }); diff --git a/packages/winnow/src/normalize-query-options/group-by.js b/packages/winnow/src/normalize-query-options/group-by.js index b7f3f203a..b9e41d13e 100644 --- a/packages/winnow/src/normalize-query-options/group-by.js +++ b/packages/winnow/src/normalize-query-options/group-by.js @@ -1,6 +1,6 @@ const { normalizeArray } = require('./helpers'); -function normalizeGroupBy (options) { +function normalizeGroupBy(options) { const groupBy = options.groupBy || options.groupByFieldsForStatistics; return normalizeArray(groupBy); } diff --git a/packages/winnow/src/normalize-query-options/group-by.spec.js b/packages/winnow/src/normalize-query-options/group-by.spec.js index 7c417f203..ff1142cf3 100644 --- a/packages/winnow/src/normalize-query-options/group-by.spec.js +++ b/packages/winnow/src/normalize-query-options/group-by.spec.js @@ -1,53 +1,58 @@ const test = require('tape'); const normalizeGroupBy = require('./group-by'); -test('normalize-options, groupBy: undefined', t => { +test('normalize-options, groupBy: undefined', (t) => { t.plan(1); - const normalized = normalizeGroupBy({ }); + const normalized = normalizeGroupBy({}); t.equal(normalized, undefined); }); -test('normalize-options, groupBy: defer to "groupBy" value', t => { +test('normalize-options, groupBy: defer to "groupBy" value', (t) => { t.plan(1); - const normalizedOrder = normalizeGroupBy({ groupBy: 'hello', groupByFieldsForStatistics: 'world' }); + const normalizedOrder = normalizeGroupBy({ + groupBy: 'hello', + groupByFieldsForStatistics: 'world', + }); t.deepEquals(normalizedOrder, ['hello']); }); -test('normalize-options, groupBy: use "groupByFieldsForStatistics" as second choice', t => { +test('normalize-options, groupBy: use "groupByFieldsForStatistics" as second choice', (t) => { t.plan(1); - const normalizedOrder = normalizeGroupBy({ groupByFieldsForStatistics: 'world' }); + const normalizedOrder = normalizeGroupBy({ + groupByFieldsForStatistics: 'world', + }); t.deepEquals(normalizedOrder, ['world']); }); -test('normalize-options, groupBy: convert string to array', t => { +test('normalize-options, groupBy: convert string to array', (t) => { t.plan(1); const normalizedOrder = normalizeGroupBy({ groupBy: 'hello,world' }); t.deepEquals(normalizedOrder, ['hello', 'world']); }); -test('normalize-options, groupBy: convert string to array, trim whitespace', t => { +test('normalize-options, groupBy: convert string to array, trim whitespace', (t) => { t.plan(1); const normalizedOrder = normalizeGroupBy({ groupBy: 'hello ,world' }); t.deepEquals(normalizedOrder, ['hello', 'world']); }); -test('normalize-options, groupBy: value is a string array', t => { +test('normalize-options, groupBy: value is a string array', (t) => { t.plan(2); const options = { - groupBy: ['test', 'field', 'names'] + groupBy: ['test', 'field', 'names'], }; const order = normalizeGroupBy(options); t.ok(Array.isArray(order)); t.deepEquals(order, ['test', 'field', 'names']); }); -test('normalize-options, groupBy: value is a not a string or array', t => { +test('normalize-options, groupBy: value is a not a string or array', (t) => { t.plan(1); const options = { - groupBy: 1 + groupBy: 1, }; const order = normalizeGroupBy(options); t.equals(order, undefined); diff --git a/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-type.js b/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-type.js index 057a9a815..eea0ecc5c 100644 --- a/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-type.js +++ b/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-type.js @@ -1,7 +1,7 @@ const moment = require('moment'); const DATE_FORMATS = [moment.ISO_8601]; -function detectEsriFieldType (value) { +function detectEsriFieldType(value) { var type = typeof value; if (Number.isInteger(value)) { diff --git a/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-types.spec.js b/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-types.spec.js index 287c60474..e5ed353d2 100644 --- a/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-types.spec.js +++ b/packages/winnow/src/normalize-query-options/helpers/detect-esri-field-types.spec.js @@ -1,26 +1,26 @@ const test = require('tape'); const { detectEsriFieldType } = require('./'); -test('detectEsriFieldTypes: string', t => { +test('detectEsriFieldTypes: string', (t) => { t.plan(1); const type = detectEsriFieldType('a string value'); t.equals(type, 'String'); }); -test('detectEsriFieldTypes: integer', t => { +test('detectEsriFieldTypes: integer', (t) => { t.plan(1); const type = detectEsriFieldType(1); t.equals(type, 'Integer'); }); -test('detectEsriFieldTypes: double', t => { +test('detectEsriFieldTypes: double', (t) => { t.plan(1); const type = detectEsriFieldType(1.1); t.equals(type, 'Double'); }); -test('detectEsriFieldTypes: date', t => { +test('detectEsriFieldTypes: date', (t) => { t.plan(1); - const type = detectEsriFieldType((new Date()).toISOString()); + const type = detectEsriFieldType(new Date().toISOString()); t.equals(type, 'Date'); }); diff --git a/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.js b/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.js index 7def712d2..31e42a6a3 100644 --- a/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.js +++ b/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.js @@ -1,7 +1,7 @@ const _ = require('lodash'); const OGC_WGS84 = 'ogc:1.3:crs84'; -function getCollectionCrs (collection) { +function getCollectionCrs(collection) { const collectionCrs = _.get(collection, 'crs.properties.name'); if (!collectionCrs) { return; @@ -14,11 +14,13 @@ function getCollectionCrs (collection) { const crsRegex = /(?epsg|esri|sr-org|iau2000)(::|:)(?.+)/; const result = crsRegex.exec(crs); - + if (!result) { return; } - const { groups: { srid } } = result; + const { + groups: { srid }, + } = result; return srid; } diff --git a/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.spec.js b/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.spec.js index f0ed26cec..7cf8b995d 100644 --- a/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.spec.js +++ b/packages/winnow/src/normalize-query-options/helpers/get-collection-crs.spec.js @@ -1,38 +1,42 @@ const test = require('tape'); const { getCollectionCrs } = require('./'); -test('getCollectionCrs: no collection', t => { +test('getCollectionCrs: no collection', (t) => { t.plan(1); const crs = getCollectionCrs(); t.equals(crs, undefined); }); -test('getCollectionCrs: no crs', t => { +test('getCollectionCrs: no crs', (t) => { t.plan(1); const crs = getCollectionCrs({}); t.equals(crs, undefined); }); -test('getCollectionCrs: no crs object', t => { +test('getCollectionCrs: no crs object', (t) => { t.plan(1); const crs = getCollectionCrs({ crs: {} }); t.equals(crs, undefined); }); -test('getCollectionCrs: bad crs definition', t => { +test('getCollectionCrs: bad crs definition', (t) => { t.plan(1); const crs = getCollectionCrs({ crs: { properties: { name: 'foodbar' } } }); t.equals(crs, undefined); }); -test('getCollectionCrs: WGS84 definition', t => { +test('getCollectionCrs: WGS84 definition', (t) => { t.plan(1); - const crs = getCollectionCrs({ crs: { properties: { name: 'urn:ogc:def:crs:ogc:1.3:crs84' } } }); + const crs = getCollectionCrs({ + crs: { properties: { name: 'urn:ogc:def:crs:ogc:1.3:crs84' } }, + }); t.equals(crs, undefined); }); -test('getCollectionCrs: non-WGS84 definition', t => { +test('getCollectionCrs: non-WGS84 definition', (t) => { t.plan(1); - const crs = getCollectionCrs({ crs: { properties: { name: 'urn:ogc:def:crs:EPSG::2285' } } }); + const crs = getCollectionCrs({ + crs: { properties: { name: 'urn:ogc:def:crs:EPSG::2285' } }, + }); t.equals(crs, '2285'); }); diff --git a/packages/winnow/src/normalize-query-options/helpers/index.js b/packages/winnow/src/normalize-query-options/helpers/index.js index a0eddbbfc..148df297e 100644 --- a/packages/winnow/src/normalize-query-options/helpers/index.js +++ b/packages/winnow/src/normalize-query-options/helpers/index.js @@ -1,5 +1,5 @@ module.exports = { normalizeArray: require('./normalize-array'), detectEsriFieldType: require('./detect-esri-field-type'), - getCollectionCrs: require('./get-collection-crs') + getCollectionCrs: require('./get-collection-crs'), }; diff --git a/packages/winnow/src/normalize-query-options/helpers/normalize-array.js b/packages/winnow/src/normalize-query-options/helpers/normalize-array.js index d0d3564a2..e151da8d2 100644 --- a/packages/winnow/src/normalize-query-options/helpers/normalize-array.js +++ b/packages/winnow/src/normalize-query-options/helpers/normalize-array.js @@ -1,6 +1,7 @@ -function normalizeArray (param) { +function normalizeArray(param) { if (Array.isArray(param)) return param; - if (typeof param === 'string' || param instanceof String) return param.split(',').map(item => item.trim()); + if (typeof param === 'string' || param instanceof String) + return param.split(',').map((item) => item.trim()); } module.exports = normalizeArray; diff --git a/packages/winnow/src/normalize-query-options/id-field.js b/packages/winnow/src/normalize-query-options/id-field.js index 8d373720c..370251540 100644 --- a/packages/winnow/src/normalize-query-options/id-field.js +++ b/packages/winnow/src/normalize-query-options/id-field.js @@ -4,18 +4,20 @@ const logManager = require('../log-manager'); * Ensure idField is set if metadata doesn't have a value but a field named OBJECTID is present * @param {object} metadata */ -function normalizeIdField (options, features = []) { +function normalizeIdField(options, features = []) { const metadata = _.get(options, 'collection.metadata'); const idField = extractIdField(metadata, features[0]); if (shouldWarnIdFieldIsMissingFromData(idField, features)) { - logManager.logger.debug('requested provider has "idField" assignment, but this property is not found in properties of all features.'); + logManager.logger.debug( + 'requested provider has "idField" assignment, but this property is not found in properties of all features.', + ); } return idField; } -function extractIdField ({ idField, fields } = {}, feature = {}) { +function extractIdField({ idField, fields } = {}, feature = {}) { if (idField) { return idField; } @@ -26,19 +28,20 @@ function extractIdField ({ idField, fields } = {}, feature = {}) { } const properties = feature.properties || feature.attributes; - if (_.has(properties, 'OBJECTID') && properties.OBJECTID !== null) { + if (_.has(properties, 'OBJECTID') && properties.OBJECTID !== null) { return 'OBJECTID'; } return null; } -function shouldWarnIdFieldIsMissingFromData (idField, features) { +function shouldWarnIdFieldIsMissingFromData(idField, features) { if (!idField || features.length === 0) { return; } - const propertiesFromFirstFeature = _.get(features, '[0].properties') || _.get(features, '[0].attributes', {}); + const propertiesFromFirstFeature = + _.get(features, '[0].properties') || _.get(features, '[0].attributes', {}); return propertiesFromFirstFeature[idField] === undefined; } diff --git a/packages/winnow/src/normalize-query-options/id-field.spec.js b/packages/winnow/src/normalize-query-options/id-field.spec.js index 034cde02a..06368871e 100644 --- a/packages/winnow/src/normalize-query-options/id-field.spec.js +++ b/packages/winnow/src/normalize-query-options/id-field.spec.js @@ -1,78 +1,82 @@ const test = require('tape'); const normalizeIdField = require('./id-field'); -test('normalize-query-options, idField: undefined inputs return null', spec => { +test('normalize-query-options, idField: undefined inputs return null', (spec) => { spec.plan(1); const result = normalizeIdField(); spec.equals(result, null); }); -test('normalize-query-options, idField: undefined metadata and no feature properties', spec => { +test('normalize-query-options, idField: undefined metadata and no feature properties', (spec) => { spec.plan(1); const result = normalizeIdField({}, [{}]); spec.equals(result, null); }); -test('normalize-query-options, idField: undefined metadata and feature OBJECTID', spec => { +test('normalize-query-options, idField: undefined metadata and feature OBJECTID', (spec) => { spec.plan(1); const result = normalizeIdField({}, [{ properties: {} }]); spec.equals(result, null); }); -test('normalize-query-options, idField: undefined metadata and feature OBJECTID', spec => { +test('normalize-query-options, idField: undefined metadata and feature OBJECTID', (spec) => { spec.plan(1); const result = normalizeIdField({}, [{ attributes: {} }]); spec.equals(result, null); }); -test('normalize-query-options, idField: no collection metadata', spec => { +test('normalize-query-options, idField: no collection metadata', (spec) => { spec.plan(1); const result = normalizeIdField({ collection: {} }); spec.equals(result, null); }); -test('normalize-query-options, idField: empty collection metadata', spec => { +test('normalize-query-options, idField: empty collection metadata', (spec) => { spec.plan(1); const result = normalizeIdField({ collection: { metadata: {} } }); spec.equals(result, null); }); -test('normalize-query-options, idField: set by metadata.idField', spec => { +test('normalize-query-options, idField: set by metadata.idField', (spec) => { spec.plan(1); - const result = normalizeIdField({ collection: { metadata: { idField: 'customIdField' } } }); + const result = normalizeIdField({ + collection: { metadata: { idField: 'customIdField' } }, + }); spec.equals(result, 'customIdField'); }); -test('normalize-query-options, idField: default to metadata.idField', spec => { +test('normalize-query-options, idField: default to metadata.idField', (spec) => { spec.plan(1); - const result = normalizeIdField({ - collection: { - metadata: { - idField: 'customIdField', - fields: [ - { name: 'OBJECTID' } - ] - } - } - }, [{ properties: { OBJECTID: 9999 } }]); + const result = normalizeIdField( + { + collection: { + metadata: { + idField: 'customIdField', + fields: [{ name: 'OBJECTID' }], + }, + }, + }, + [{ properties: { OBJECTID: 9999 } }], + ); spec.equals(result, 'customIdField'); }); -test('normalize-query-options, idField: derive from metadata.fields', spec => { +test('normalize-query-options, idField: derive from metadata.fields', (spec) => { spec.plan(1); - const result = normalizeIdField({ - collection: { - metadata: { - fields: [ - { name: 'OBJECTID' } - ] - } - } - }, [{ properties: { OBJECTID: 9999 } }]); + const result = normalizeIdField( + { + collection: { + metadata: { + fields: [{ name: 'OBJECTID' }], + }, + }, + }, + [{ properties: { OBJECTID: 9999 } }], + ); spec.equals(result, 'OBJECTID'); }); -test('normalize-query-options, idField: derive from data', spec => { +test('normalize-query-options, idField: derive from data', (spec) => { spec.plan(1); const result = normalizeIdField({}, [{ properties: { OBJECTID: 9999 } }]); spec.equals(result, 'OBJECTID'); diff --git a/packages/winnow/src/normalize-query-options/index.js b/packages/winnow/src/normalize-query-options/index.js index f49cede5c..bceac2e27 100644 --- a/packages/winnow/src/normalize-query-options/index.js +++ b/packages/winnow/src/normalize-query-options/index.js @@ -16,11 +16,8 @@ const normalizeLimit = require('./limit'); const normalizeOffset = require('./offset'); const normalizeObjectIds = require('./object-ids'); -function normalizeQueryOptions (options, features) { - const { - where, - collection - } = options; +function normalizeQueryOptions(options, features) { + const { where, collection } = options; const normalizedOptions = _.merge({}, options, { collection: normalizeCollection(collection, features), @@ -36,10 +33,13 @@ function normalizeQueryOptions (options, features) { outputCrs: normalizeOutputDataSpatialReference(options), inputCrs: normalizeSourceDataSpatialReference(options), classification: normalizeClassification(options), - objectIds: normalizeObjectIds(options.objectIds) + objectIds: normalizeObjectIds(options.objectIds), }); normalizedOptions.offset = normalizeOffset(normalizedOptions); - normalizedOptions.dateFields = deriveDateFields(normalizedOptions.collection, normalizedOptions.fields); + normalizedOptions.dateFields = deriveDateFields( + normalizedOptions.collection, + normalizedOptions.fields, + ); return normalizedOptions; } diff --git a/packages/winnow/src/normalize-query-options/limit.spec.js b/packages/winnow/src/normalize-query-options/limit.spec.js index 71d03852f..c1890e095 100644 --- a/packages/winnow/src/normalize-query-options/limit.spec.js +++ b/packages/winnow/src/normalize-query-options/limit.spec.js @@ -1,60 +1,60 @@ const test = require('tape'); const normalizeLimit = require('./limit'); -test('normalize-query-options, limit: undefined', t => { +test('normalize-query-options, limit: undefined', (t) => { t.plan(1); - const normalized = normalizeLimit({ }); + const normalized = normalizeLimit({}); t.equal(normalized, undefined); }); -test('normalize-query-options, limit: defer to limit option', t => { +test('normalize-query-options, limit: defer to limit option', (t) => { t.plan(1); const normalized = normalizeLimit({ limit: 10, resultRecordCount: 20, count: 30, - maxFeatures: 40 + maxFeatures: 40, }); t.equal(normalized, 11); }); -test('normalize-query-options, limit: defer to resultRecordCount option', t => { +test('normalize-query-options, limit: defer to resultRecordCount option', (t) => { t.plan(1); const normalized = normalizeLimit({ resultRecordCount: 20, count: 30, - maxFeatures: 40 + maxFeatures: 40, }); t.equal(normalized, 21); }); -test('normalize-query-options, limit: defer to count option', t => { +test('normalize-query-options, limit: defer to count option', (t) => { t.plan(1); const normalized = normalizeLimit({ count: 30, - maxFeatures: 40 + maxFeatures: 40, }); t.equal(normalized, 31); }); -test('normalize-query-options, limit: defer to maxFeatures option', t => { +test('normalize-query-options, limit: defer to maxFeatures option', (t) => { t.plan(1); const normalized = normalizeLimit({ - maxFeatures: 40 + maxFeatures: 40, }); t.equal(normalized, 41); }); -test('normalize-query-options, limit: undefined if not an integer', t => { +test('normalize-query-options, limit: undefined if not an integer', (t) => { t.plan(1); const normalized = normalizeLimit({ - limit: '1' + limit: '1', }); t.equal(normalized, undefined); }); diff --git a/packages/winnow/src/normalize-query-options/object-ids.spec.js b/packages/winnow/src/normalize-query-options/object-ids.spec.js index 45de00ad3..8fe74aea7 100644 --- a/packages/winnow/src/normalize-query-options/object-ids.spec.js +++ b/packages/winnow/src/normalize-query-options/object-ids.spec.js @@ -1,49 +1,49 @@ const test = require('tape'); const normalizeObjectIds = require('./object-ids'); -test('normalize objectIds: undefined objectIds', t => { +test('normalize objectIds: undefined objectIds', (t) => { t.plan(1); const normalized = normalizeObjectIds(); t.equal(normalized, undefined); }); -test('normalize objectIds: numeric string', t => { +test('normalize objectIds: numeric string', (t) => { t.plan(1); const normalized = normalizeObjectIds('1'); t.deepEqual(normalized, [1]); }); -test('normalize objectIds: delimited numeric string', t => { +test('normalize objectIds: delimited numeric string', (t) => { t.plan(1); const normalized = normalizeObjectIds('1,2'); t.deepEqual(normalized, [1, 2]); }); -test('normalize objectIds: delimited strings', t => { +test('normalize objectIds: delimited strings', (t) => { t.plan(1); const normalized = normalizeObjectIds('abc3ef,xyz123'); - t.deepEqual(normalized, ['abc3ef','xyz123']); + t.deepEqual(normalized, ['abc3ef', 'xyz123']); }); -test('normalize objectIds: integer', t => { +test('normalize objectIds: integer', (t) => { t.plan(1); const normalized = normalizeObjectIds(1); t.deepEqual(normalized, [1]); }); -test('normalize objectIds: numeric array', t => { +test('normalize objectIds: numeric array', (t) => { t.plan(1); const normalized = normalizeObjectIds([1]); t.deepEqual(normalized, [1]); }); -test('normalize objectIds: throw on unsupported data type', t => { +test('normalize objectIds: throw on unsupported data type', (t) => { t.plan(2); try { diff --git a/packages/winnow/src/normalize-query-options/offset.js b/packages/winnow/src/normalize-query-options/offset.js index 17d5e0af1..bd44c3de6 100644 --- a/packages/winnow/src/normalize-query-options/offset.js +++ b/packages/winnow/src/normalize-query-options/offset.js @@ -4,8 +4,10 @@ * @param {object} options * @returns {integer} or undefined */ -function normalizeOffset (options) { - return (options.limit !== undefined) ? (options.offset || options.resultOffset) : undefined; +function normalizeOffset(options) { + return options.limit !== undefined + ? options.offset || options.resultOffset + : undefined; } module.exports = normalizeOffset; diff --git a/packages/winnow/src/normalize-query-options/offset.spec.js b/packages/winnow/src/normalize-query-options/offset.spec.js index 601ba1de3..08327c2e7 100644 --- a/packages/winnow/src/normalize-query-options/offset.spec.js +++ b/packages/winnow/src/normalize-query-options/offset.spec.js @@ -1,39 +1,39 @@ const test = require('tape'); const normalizeOffset = require('./offset'); -test('normalize-query-options, offset: undefined limit and offset', t => { +test('normalize-query-options, offset: undefined limit and offset', (t) => { t.plan(1); - const normalized = normalizeOffset({ }); + const normalized = normalizeOffset({}); t.equal(normalized, undefined); }); -test('normalize-query-options, offset: undefined limit', t => { +test('normalize-query-options, offset: undefined limit', (t) => { t.plan(1); const normalized = normalizeOffset({ - offset: 100 + offset: 100, }); t.equal(normalized, undefined); }); -test('normalize-query-options, offset: defer to offset option', t => { +test('normalize-query-options, offset: defer to offset option', (t) => { t.plan(1); const normalized = normalizeOffset({ limit: 10, offset: 100, - resultOffset: 200 + resultOffset: 200, }); t.equal(normalized, 100); }); -test('normalize-query-options, offset: defer to resultOffset option if no offset', t => { +test('normalize-query-options, offset: defer to resultOffset option if no offset', (t) => { t.plan(1); const normalized = normalizeOffset({ limit: 10, - resultOffset: 200 + resultOffset: 200, }); t.equal(normalized, 200); }); diff --git a/packages/winnow/src/normalize-query-options/order.js b/packages/winnow/src/normalize-query-options/order.js index 534398c57..a399e11d5 100644 --- a/packages/winnow/src/normalize-query-options/order.js +++ b/packages/winnow/src/normalize-query-options/order.js @@ -1,6 +1,6 @@ const { normalizeArray } = require('./helpers'); -function normalizeOrder (options) { +function normalizeOrder(options) { const order = options.order || options.orderByFields; if (!order) return; return normalizeArray(order); diff --git a/packages/winnow/src/normalize-query-options/order.spec.js b/packages/winnow/src/normalize-query-options/order.spec.js index 843ff1243..6eb2e697e 100644 --- a/packages/winnow/src/normalize-query-options/order.spec.js +++ b/packages/winnow/src/normalize-query-options/order.spec.js @@ -1,60 +1,63 @@ const test = require('tape'); const normalizeOrder = require('./order'); -test('normalize-options, order: undefined', t => { +test('normalize-options, order: undefined', (t) => { t.plan(1); - const normalized = normalizeOrder({ }); + const normalized = normalizeOrder({}); t.equal(normalized, undefined); }); -test('normalize-options, order: empty string', t => { +test('normalize-options, order: empty string', (t) => { t.plan(1); const normalized = normalizeOrder({ order: '' }); t.equal(normalized, undefined); }); -test('normalize-options, order: defer to "order" value', t => { +test('normalize-options, order: defer to "order" value', (t) => { t.plan(1); - const normalizedOrder = normalizeOrder({ order: 'hello', orderByFields: 'world' }); + const normalizedOrder = normalizeOrder({ + order: 'hello', + orderByFields: 'world', + }); t.deepEquals(normalizedOrder, ['hello']); }); -test('normalize-options, order: use orderByFields as second choice', t => { +test('normalize-options, order: use orderByFields as second choice', (t) => { t.plan(1); const normalizedOrder = normalizeOrder({ orderByFields: 'world' }); t.deepEquals(normalizedOrder, ['world']); }); -test('normalize-options, order: convert string to array', t => { +test('normalize-options, order: convert string to array', (t) => { t.plan(1); const normalizedOrder = normalizeOrder({ order: 'hello,world' }); t.deepEquals(normalizedOrder, ['hello', 'world']); }); -test('normalize-options, order: convert string to array, trim whitespace', t => { +test('normalize-options, order: convert string to array, trim whitespace', (t) => { t.plan(1); const normalizedOrder = normalizeOrder({ order: 'hello ,world' }); t.deepEquals(normalizedOrder, ['hello', 'world']); }); -test('normalize-options, order: value is a string array', t => { +test('normalize-options, order: value is a string array', (t) => { t.plan(2); const options = { - order: ['test', 'field', 'names'] + order: ['test', 'field', 'names'], }; const order = normalizeOrder(options); t.ok(Array.isArray(order)); t.deepEquals(order, ['test', 'field', 'names']); }); -test('normalize-options, order: value is a not a string or array', t => { +test('normalize-options, order: value is a not a string or array', (t) => { t.plan(1); const options = { - order: 1 + order: 1, }; const order = normalizeOrder(options); t.equals(order, undefined); diff --git a/packages/winnow/src/normalize-query-options/output-data-spatial-reference.js b/packages/winnow/src/normalize-query-options/output-data-spatial-reference.js index 5047926c4..944625304 100644 --- a/packages/winnow/src/normalize-query-options/output-data-spatial-reference.js +++ b/packages/winnow/src/normalize-query-options/output-data-spatial-reference.js @@ -2,7 +2,7 @@ const normalizeSpatialReference = require('./spatial-reference'); const { getCollectionCrs } = require('./helpers'); const logManager = require('../log-manager'); -function normalizeOutputDataSpatialReference (options = {}) { +function normalizeOutputDataSpatialReference(options = {}) { const { srsname, srsName, @@ -11,16 +11,27 @@ function normalizeOutputDataSpatialReference (options = {}) { outSR, inputCrs, sourceSR, - collection + collection, } = options; // if no output spatial reference set (outputCrs, projection, srsname, srsName, outSR), assume output will be same as input (inputCrs, sourceSR) - const outputSpatialReference = outputCrs || projection || srsname || srsName || outSR || inputCrs || sourceSR || getCollectionCrs(collection) || 4326; + const outputSpatialReference = + outputCrs || + projection || + srsname || + srsName || + outSR || + inputCrs || + sourceSR || + getCollectionCrs(collection) || + 4326; const spatialReference = normalizeSpatialReference(outputSpatialReference); if (!spatialReference) { - logManager.logger.debug(`spatial reference "${outputSpatialReference}" could not be normalized. Defaulting to EPSG:4326.`); + logManager.logger.debug( + `spatial reference "${outputSpatialReference}" could not be normalized. Defaulting to EPSG:4326.`, + ); // @TODO: throw error } diff --git a/packages/winnow/src/normalize-query-options/output-data-spatial-reference.spec.js b/packages/winnow/src/normalize-query-options/output-data-spatial-reference.spec.js index 531d71e36..4e5ec4847 100644 --- a/packages/winnow/src/normalize-query-options/output-data-spatial-reference.spec.js +++ b/packages/winnow/src/normalize-query-options/output-data-spatial-reference.spec.js @@ -1,97 +1,109 @@ const test = require('tape'); const normalizeOutputDataSpatialReference = require('./output-data-spatial-reference'); -test('normalize-query-options, output-data-spatial-reference: undefined input', t => { +test('normalize-query-options, output-data-spatial-reference: undefined input', (t) => { t.plan(1); const { wkid } = normalizeOutputDataSpatialReference(); t.equal(wkid, 4326); }); -test('normalize-query-options, output-data-spatial-reference: undefined options', t => { +test('normalize-query-options, output-data-spatial-reference: undefined options', (t) => { t.plan(1); const { wkid } = normalizeOutputDataSpatialReference({}); t.equal(wkid, 4326); }); -test('normalize-query-options, output-data-spatial-reference: defer to projection option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to projection option', (t) => { t.plan(1); const options = { projection: 4326, srsname: 4269, srsName: 3857, - outSR: 2227 + outSR: 2227, }; const { wkid } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 4326); }); -test('normalize-query-options, output-data-spatial-reference: defer to srsname option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to srsname option', (t) => { t.plan(1); const options = { srsname: 4269, srsName: 3857, - outSR: 2227 + outSR: 2227, }; const { wkid } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 4269); }); -test('normalize-query-options, output-data-spatial-reference: defer to srsName option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to srsName option', (t) => { t.plan(1); const options = { srsName: 3857, - outSR: 2227 + outSR: 2227, }; const { wkid } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 3857); }); -test('normalize-query-options, output-data-spatial-reference: defer to outSR option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to outSR option', (t) => { t.plan(2); const options = { - outSR: 2227 + outSR: 2227, }; const { wkid, wkt } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 2227); - t.equal(wkt, 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]'); + t.equal( + wkt, + 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]', + ); }); -test('normalize-query-options, output-data-spatial-reference: defer to inputCrs option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to inputCrs option', (t) => { t.plan(2); const options = { - inputCrs: 2227 + inputCrs: 2227, }; const { wkid, wkt } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 2227); - t.equal(wkt, 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]'); + t.equal( + wkt, + 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]', + ); }); -test('normalize-query-options, output-data-spatial-reference: defer to sourceSR option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to sourceSR option', (t) => { t.plan(2); const options = { - sourceSR: 2227 + sourceSR: 2227, }; const { wkid, wkt } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 2227); - t.equal(wkt, 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]'); + t.equal( + wkt, + 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]', + ); }); -test('normalize-query-options, output-data-spatial-reference: defer to collection.crs option', t => { +test('normalize-query-options, output-data-spatial-reference: defer to collection.crs option', (t) => { t.plan(2); const options = { collection: { - crs: { properties: { name: 'urn:ogc:def:crs:EPSG:2227' } } - } + crs: { properties: { name: 'urn:ogc:def:crs:EPSG:2227' } }, + }, }; const { wkid, wkt } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 2227); - t.equal(wkt, 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]'); + t.equal( + wkt, + 'PROJCS["NAD_1983_StatePlane_California_III_FIPS_0403_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-120.5],PARAMETER["Standard_Parallel_1",37.06666666666667],PARAMETER["Standard_Parallel_2",38.43333333333333],PARAMETER["Latitude_Of_Origin",36.5],UNIT["Foot_US",0.3048006096012192]]', + ); }); -test('normalize-query-options, output-data-spatial-reference: bad input', t => { +test('normalize-query-options, output-data-spatial-reference: bad input', (t) => { t.plan(1); const options = { - outSR: 99999 + outSR: 99999, }; const { wkid } = normalizeOutputDataSpatialReference(options); t.equal(wkid, 4326); diff --git a/packages/winnow/src/normalize-query-options/source-data-spatial-reference.js b/packages/winnow/src/normalize-query-options/source-data-spatial-reference.js index 34da921a2..99e6de176 100644 --- a/packages/winnow/src/normalize-query-options/source-data-spatial-reference.js +++ b/packages/winnow/src/normalize-query-options/source-data-spatial-reference.js @@ -2,14 +2,23 @@ const normalizeSpatialReference = require('./spatial-reference'); const { getCollectionCrs } = require('./helpers'); const logManager = require('../log-manager'); -function normalizeSourceDataSpatialReference ({ inputCrs, sourceSR, collection } = {}) { - const sourceDataSpatialReference = inputCrs || sourceSR || getCollectionCrs(collection); +function normalizeSourceDataSpatialReference({ + inputCrs, + sourceSR, + collection, +} = {}) { + const sourceDataSpatialReference = + inputCrs || sourceSR || getCollectionCrs(collection); if (!sourceDataSpatialReference) return { wkid: 4326 }; - const spatialReference = normalizeSpatialReference(sourceDataSpatialReference); + const spatialReference = normalizeSpatialReference( + sourceDataSpatialReference, + ); if (!spatialReference) { - logManager.logger.debug(`spatial reference "${sourceDataSpatialReference}" could not be normalized. Defaulting to EPSG:4326.`); + logManager.logger.debug( + `spatial reference "${sourceDataSpatialReference}" could not be normalized. Defaulting to EPSG:4326.`, + ); // @TODO: throw error? } return spatialReference || { wkid: 4326 }; diff --git a/packages/winnow/src/normalize-query-options/source-data-spatial-reference.spec.js b/packages/winnow/src/normalize-query-options/source-data-spatial-reference.spec.js index 6f2795032..ceac6b122 100644 --- a/packages/winnow/src/normalize-query-options/source-data-spatial-reference.spec.js +++ b/packages/winnow/src/normalize-query-options/source-data-spatial-reference.spec.js @@ -1,59 +1,62 @@ const test = require('tape'); const normalizeSourceDataSpatialReference = require('./source-data-spatial-reference'); -test('normalize-query-options, source-data-spatial-reference: undefined input', t => { +test('normalize-query-options, source-data-spatial-reference: undefined input', (t) => { t.plan(1); const { wkid } = normalizeSourceDataSpatialReference(); t.equal(wkid, 4326); }); -test('normalize-query-options, source-data-spatial-reference: known spatial reference', t => { +test('normalize-query-options, source-data-spatial-reference: known spatial reference', (t) => { t.plan(1); const { wkid } = normalizeSourceDataSpatialReference({ inputCrs: 3857 }); t.equal(wkid, 3857); }); -test('normalize-query-options, source-data-spatial-reference: spatial reference that requires wkt', t => { +test('normalize-query-options, source-data-spatial-reference: spatial reference that requires wkt', (t) => { t.plan(2); const { wkid, wkt } = normalizeSourceDataSpatialReference({ inputCrs: 2228 }); t.equal(wkid, 2228); - t.equal(wkt, 'PROJCS["NAD_1983_StatePlane_California_IV_FIPS_0404_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-119.0],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Standard_Parallel_2",37.25],PARAMETER["Latitude_Of_Origin",35.33333333333334],UNIT["Foot_US",0.3048006096012192]]'); + t.equal( + wkt, + 'PROJCS["NAD_1983_StatePlane_California_IV_FIPS_0404_Feet",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",6561666.666666666],PARAMETER["False_Northing",1640416.666666667],PARAMETER["Central_Meridian",-119.0],PARAMETER["Standard_Parallel_1",36.0],PARAMETER["Standard_Parallel_2",37.25],PARAMETER["Latitude_Of_Origin",35.33333333333334],UNIT["Foot_US",0.3048006096012192]]', + ); }); -test('normalize-query-options, source-data-spatial-reference: sourceSR option', t => { +test('normalize-query-options, source-data-spatial-reference: sourceSR option', (t) => { t.plan(1); const { wkid } = normalizeSourceDataSpatialReference({ sourceSR: 3857 }); t.equal(wkid, 3857); }); -test('normalize-query-options, source-data-spatial-reference: collection crs', t => { +test('normalize-query-options, source-data-spatial-reference: collection crs', (t) => { t.plan(1); const params = { collection: { - crs: { properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } } - } + crs: { properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' } }, + }, }; const { wkid } = normalizeSourceDataSpatialReference(params); t.equal(wkid, 4326); }); -test('normalize-query-options, source-data-spatial-reference: collection crs', t => { +test('normalize-query-options, source-data-spatial-reference: collection crs', (t) => { t.plan(1); const params = { collection: { - crs: { properties: { name: 'urn:ogc:def:crs:EPSG::3857' } } - } + crs: { properties: { name: 'urn:ogc:def:crs:EPSG::3857' } }, + }, }; const { wkid } = normalizeSourceDataSpatialReference(params); t.equal(wkid, 3857); }); -test('normalize-query-options, source-data-spatial-reference: known spatial reference', t => { +test('normalize-query-options, source-data-spatial-reference: known spatial reference', (t) => { t.plan(1); const params = { collection: { - crs: { properties: { name: 'urn:ogc:def:crs:EPSG:3857' } } - } + crs: { properties: { name: 'urn:ogc:def:crs:EPSG:3857' } }, + }, }; const { wkid } = normalizeSourceDataSpatialReference(params); t.equal(wkid, 3857); diff --git a/packages/winnow/src/normalize-query-options/spatial-predicate.js b/packages/winnow/src/normalize-query-options/spatial-predicate.js index b5f50970a..b01592e99 100644 --- a/packages/winnow/src/normalize-query-options/spatial-predicate.js +++ b/packages/winnow/src/normalize-query-options/spatial-predicate.js @@ -2,10 +2,10 @@ const esriPredicates = { esriSpatialRelContains: 'ST_Contains', esriSpatialRelWithin: 'ST_Within', esriSpatialRelIntersects: 'ST_Intersects', - esriSpatialRelEnvelopeIntersects: 'ST_EnvelopeIntersects' + esriSpatialRelEnvelopeIntersects: 'ST_EnvelopeIntersects', }; -function normalizeSpatialPredicate ({ spatialPredicate, spatialRel } = {}) { +function normalizeSpatialPredicate({ spatialPredicate, spatialRel } = {}) { const predicate = spatialPredicate || spatialRel; return esriPredicates[predicate] || predicate; } diff --git a/packages/winnow/src/normalize-query-options/spatial-predicate.spec.js b/packages/winnow/src/normalize-query-options/spatial-predicate.spec.js index b56983ec5..25448a30d 100644 --- a/packages/winnow/src/normalize-query-options/spatial-predicate.spec.js +++ b/packages/winnow/src/normalize-query-options/spatial-predicate.spec.js @@ -1,51 +1,65 @@ const test = require('tape'); const normalizeSpatialPredicate = require('./spatial-predicate'); -test('normalize-query-options, spatial-predicate: undefined', t => { +test('normalize-query-options, spatial-predicate: undefined', (t) => { t.plan(1); const normalized = normalizeSpatialPredicate(undefined); t.equal(normalized, undefined); }); -test('normalize-options, spatial-predicate: defer to "spatialPredicate" value', t => { +test('normalize-options, spatial-predicate: defer to "spatialPredicate" value', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'hello', spatialRel: 'world' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'hello', + spatialRel: 'world', + }); t.deepEquals(normalizedOrder, 'hello'); }); -test('normalize-options, spatial-predicate: defer to "spatialPredicate" value', t => { +test('normalize-options, spatial-predicate: defer to "spatialPredicate" value', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'hello', spatialRel: 'world' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'hello', + spatialRel: 'world', + }); t.deepEquals(normalizedOrder, 'hello'); }); -test('normalize-options, spatial-predicate: normalize esriSpatialRelContains ', t => { +test('normalize-options, spatial-predicate: normalize esriSpatialRelContains ', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'esriSpatialRelContains' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'esriSpatialRelContains', + }); t.deepEquals(normalizedOrder, 'ST_Contains'); }); -test('normalize-options, spatial-predicate: normalize esriSpatialRelWithin', t => { +test('normalize-options, spatial-predicate: normalize esriSpatialRelWithin', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'esriSpatialRelWithin' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'esriSpatialRelWithin', + }); t.deepEquals(normalizedOrder, 'ST_Within'); }); -test('normalize-options, spatial-predicate: normalize esriSpatialRelIntersects', t => { +test('normalize-options, spatial-predicate: normalize esriSpatialRelIntersects', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'esriSpatialRelIntersects' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'esriSpatialRelIntersects', + }); t.deepEquals(normalizedOrder, 'ST_Intersects'); }); -test('normalize-options, spatial-predicate: normalize esriSpatialRelEnvelopeIntersects', t => { +test('normalize-options, spatial-predicate: normalize esriSpatialRelEnvelopeIntersects', (t) => { t.plan(1); - const normalizedOrder = normalizeSpatialPredicate({ spatialPredicate: 'esriSpatialRelEnvelopeIntersects' }); + const normalizedOrder = normalizeSpatialPredicate({ + spatialPredicate: 'esriSpatialRelEnvelopeIntersects', + }); t.deepEquals(normalizedOrder, 'ST_EnvelopeIntersects'); }); diff --git a/packages/winnow/src/normalize-query-options/spatial-reference.js b/packages/winnow/src/normalize-query-options/spatial-reference.js index 769da7e83..18fbc4469 100644 --- a/packages/winnow/src/normalize-query-options/spatial-reference.js +++ b/packages/winnow/src/normalize-query-options/spatial-reference.js @@ -10,18 +10,21 @@ const schema = Joi.alternatives( Joi.object({ wkid: Joi.number().integer().optional(), latestWkid: Joi.number().integer().optional(), - wkt: Joi.string().optional() - }).or('wkid', 'latestWkid', 'wkt') - .unknown() + wkt: Joi.string().optional(), + }) + .or('wkid', 'latestWkid', 'wkt') + .unknown(), ); -function normalizeSpatialReference (input) { +function normalizeSpatialReference(input) { if (!input) return; const { error } = schema.validate(input); if (error) { - logManager.logger.debug(`${input} is not a valid spatial reference; defaulting to none`); + logManager.logger.debug( + `${input} is not a valid spatial reference; defaulting to none`, + ); // Todo: throw error return; } @@ -35,49 +38,54 @@ function normalizeSpatialReference (input) { return convertStringToSpatialReference(value); } -function parseSpatialReferenceInput (spatialReference) { +function parseSpatialReferenceInput(spatialReference) { // Search input for a wkid if (isNumericSpatialReferenceId(spatialReference)) { return { type: 'wkid', - value: Number(spatialReference) + value: Number(spatialReference), }; } if (isPrefixedSpatialReferenceId(spatialReference)) { return { type: 'wkid', - value: extractPrefixedSpatialReferenceId(spatialReference) + value: extractPrefixedSpatialReferenceId(spatialReference), }; } if (spatialReference.wkid || spatialReference.latestWkid) { return { type: 'wkid', - value: spatialReference.latestWkid || spatialReference.wkid + value: spatialReference.latestWkid || spatialReference.wkid, }; } return { type: 'wkt', - value: spatialReference.wkt || spatialReference + value: spatialReference.wkt || spatialReference, }; } -function isNumericSpatialReferenceId (spatialReference) { - return Number.isInteger(spatialReference) || Number.isInteger(Number(spatialReference)); +function isNumericSpatialReferenceId(spatialReference) { + return ( + Number.isInteger(spatialReference) || + Number.isInteger(Number(spatialReference)) + ); } -function isPrefixedSpatialReferenceId (spatialReference) { +function isPrefixedSpatialReferenceId(spatialReference) { return /^(EPSG|ESRI|SR-ORG|IAU2000):[0-9]+/.test(spatialReference); } -function extractPrefixedSpatialReferenceId (prefixedId) { - const spatialRefId = prefixedId.match(/^(EPSG|ESRI|SR-ORG|IAU2000):([0-9]+)/)[2]; +function extractPrefixedSpatialReferenceId(prefixedId) { + const spatialRefId = prefixedId.match( + /^(EPSG|ESRI|SR-ORG|IAU2000):([0-9]+)/, + )[2]; return Number(spatialRefId); } -function convertWkidToSpatialReference (wkid) { +function convertWkidToSpatialReference(wkid) { // 102100 is the old Esri code for 3857 but not recognized for proj4 if (wkid === 102100) return { wkid: 3857 }; @@ -88,12 +96,14 @@ function convertWkidToSpatialReference (wkid) { return wktLookup.get(wkid) || esriWktLookup(wkid); } -function esriWktLookup (wkid) { +function esriWktLookup(wkid) { const result = esriProjCodes.lookup(wkid); if (!result) { // Todo - throw error - logManager.logger.debug(`An unknown spatial reference was detected: ${wkid}; defaulting to none`); + logManager.logger.debug( + `An unknown spatial reference was detected: ${wkid}; defaulting to none`, + ); return; } @@ -104,22 +114,24 @@ function esriWktLookup (wkid) { return { wkid, wkt }; } -function convertStringToSpatialReference (wkt) { +function convertStringToSpatialReference(wkt) { if (/WGS_1984_Web_Mercator_Auxiliary_Sphere/.test(wkt)) return { wkid: 3857 }; try { const wkid = getWktWkid(wkt); return { wkt, - wkid: wkid ? Number(wkid) : undefined + wkid: wkid ? Number(wkid) : undefined, }; } catch (err) { - logManager.logger.debug(`An un-parseable WKT spatial reference was detected: ${wkt}`); + logManager.logger.debug( + `An un-parseable WKT spatial reference was detected: ${wkt}; ${err.message}`, + ); // Todo: throw error } } -function getWktWkid (wkt) { +function getWktWkid(wkt) { const { AUTHORITY: authority } = wktParser(wkt); if (!authority) return; const [, wkid] = Object.entries(authority)[0]; diff --git a/packages/winnow/src/normalize-query-options/spatial-reference.spec.js b/packages/winnow/src/normalize-query-options/spatial-reference.spec.js index b869690f1..49ce41a7f 100644 --- a/packages/winnow/src/normalize-query-options/spatial-reference.spec.js +++ b/packages/winnow/src/normalize-query-options/spatial-reference.spec.js @@ -1,56 +1,57 @@ const test = require('tape'); const normalizeSpatialReference = require('./spatial-reference'); -test('normalize-query-options, spatial-reference: undefined', t => { +test('normalize-query-options, spatial-reference: undefined', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference(); t.equal(spatialRef, undefined); }); -test('normalize-query-options, spatial-reference: invalid type', t => { +test('normalize-query-options, spatial-reference: invalid type', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference(true); t.equal(spatialRef, undefined); }); -test('normalize-query-options, spatial-reference: invalid object', t => { +test('normalize-query-options, spatial-reference: invalid object', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference({ test: 'foo' }); t.equal(spatialRef, undefined); }); -test('normalize-query-options, spatial-reference: invalid wkid', t => { +test('normalize-query-options, spatial-reference: invalid wkid', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference(99999); t.equal(spatialRef, undefined); }); -test('normalize-query-options, spatial-reference: invalid wkt', t => { +test('normalize-query-options, spatial-reference: invalid wkt', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference('foodbar'); t.equal(spatialRef, undefined); }); -test('normalize-query-options, spatial-reference: object with wkid from proj4 list', t => { +test('normalize-query-options, spatial-reference: object with wkid from proj4 list', (t) => { t.plan(1); const { wkid } = normalizeSpatialReference({ wkid: 4269 }); t.equal(wkid, 4269); }); -test('normalize-query-options, spatial-reference: object with latest wkid from proj4 list', t => { +test('normalize-query-options, spatial-reference: object with latest wkid from proj4 list', (t) => { t.plan(1); const { wkid } = normalizeSpatialReference({ latestWkid: 4269 }); t.equal(wkid, 4269); }); -test('normalize-query-options, spatial-reference: object with wkt that is Web Mercator string', t => { +test('normalize-query-options, spatial-reference: object with wkt that is Web Mercator string', (t) => { t.plan(1); - const inputWkt = 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; + const inputWkt = + 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; const { wkid } = normalizeSpatialReference({ wkt: inputWkt }); t.equal(wkid, 3857); }); -test('normalize-query-options, spatial-reference: object with wkt that is not Web Mercator string', t => { +test('normalize-query-options, spatial-reference: object with wkt that is not Web Mercator string', (t) => { t.plan(2); const inputWkt = `PROJCS["NAD_1983_StatePlane_California_V_FIPS_0405_Feet", GEOGCS["GCS_North_American_1983", @@ -72,14 +73,15 @@ test('normalize-query-options, spatial-reference: object with wkt that is not We t.equal(wkid, 102645); }); -test('normalize-query-options, spatial-reference: Web Mercator wkt string', t => { +test('normalize-query-options, spatial-reference: Web Mercator wkt string', (t) => { t.plan(1); - const inputWkt = 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; + const inputWkt = + 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]'; const { wkid } = normalizeSpatialReference(inputWkt); t.equal(wkid, 3857); }); -test('normalize-query-options, spatial-reference: non Web Mercator wkt string', t => { +test('normalize-query-options, spatial-reference: non Web Mercator wkt string', (t) => { t.plan(2); const inputWkt = `PROJCS["NAD_1983_StatePlane_California_V_FIPS_0405_Feet", GEOGCS["GCS_North_American_1983", @@ -101,33 +103,34 @@ test('normalize-query-options, spatial-reference: non Web Mercator wkt string', t.equal(wkid, 102645); }); -test('normalize-query-options, spatial-reference: prefixed wkid', t => { +test('normalize-query-options, spatial-reference: prefixed wkid', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference('EPSG:3857'); t.equal(spatialRef.wkid, 3857); }); -test('normalize-query-options, spatial-reference: wkid number', t => { +test('normalize-query-options, spatial-reference: wkid number', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference(3857); t.equal(spatialRef.wkid, 3857); }); -test('normalize-query-options, spatial-reference: wkid 102100', t => { +test('normalize-query-options, spatial-reference: wkid 102100', (t) => { t.plan(1); const spatialRef = normalizeSpatialReference(102100); t.equal(spatialRef.wkid, 3857); }); -test('normalize-query-options, spatial-reference: wkid not in Proj4 list', t => { +test('normalize-query-options, spatial-reference: wkid not in Proj4 list', (t) => { t.plan(2); - const inputWkt = 'PROJCS["NAD_1983_HARN_StatePlane_Washington_North_FIPS_4601",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-120.8333333333333],PARAMETER["Standard_Parallel_1",47.5],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Meter",1.0]]'; + const inputWkt = + 'PROJCS["NAD_1983_HARN_StatePlane_Washington_North_FIPS_4601",GEOGCS["GCS_North_American_1983_HARN",DATUM["D_North_American_1983_HARN",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-120.8333333333333],PARAMETER["Standard_Parallel_1",47.5],PARAMETER["Standard_Parallel_2",48.73333333333333],PARAMETER["Latitude_Of_Origin",47.0],UNIT["Meter",1.0]]'; const { wkt, wkid } = normalizeSpatialReference(2855); t.equal(wkt, inputWkt); t.equal(wkid, 2855); }); -test('normalize-query-options, spatial-reference: object with wkid and other optional properties', t => { +test('normalize-query-options, spatial-reference: object with wkid and other optional properties', (t) => { t.plan(1); const { wkid } = normalizeSpatialReference({ wkid: 102643, @@ -141,7 +144,7 @@ test('normalize-query-options, spatial-reference: object with wkid and other opt falseZ: -100000, zUnits: 10000, falseM: -100000, - mUnits: 10000 + mUnits: 10000, }); t.equal(wkid, 2227); }); diff --git a/packages/winnow/src/normalize-query-options/where.js b/packages/winnow/src/normalize-query-options/where.js index c36e6d9d2..97fbc70ab 100644 --- a/packages/winnow/src/normalize-query-options/where.js +++ b/packages/winnow/src/normalize-query-options/where.js @@ -1,8 +1,8 @@ const _ = require('lodash'); const { InvalidWhereParameterError } = require('../errors'); -function normalizeWhere (where = '') { - if(!_.isString(where)) { +function normalizeWhere(where = '') { + if (!_.isString(where)) { throw new InvalidWhereParameterError('must be a string if defined'); } @@ -13,23 +13,26 @@ function normalizeWhere (where = '') { if (containsSqlDates(where)) { return convertToISODates(where); } - + return where; } -function convertToISODates (where) { +function convertToISODates(where) { const matches = where.match(/(?!date )('?\d\d\d\d-\d\d-\d\d'?)/g); - matches.forEach(match => { - where = where.replace(`date ${match}`, `'${new Date(match.toString()).toISOString()}'`); + matches.forEach((match) => { + where = where.replace( + `date ${match}`, + `'${new Date(match.toString()).toISOString()}'`, + ); }); return where; } -function isEsriSelectAll (where) { +function isEsriSelectAll(where) { return /1\s*=\s*1/.test(where); } -function containsSqlDates (where) { +function containsSqlDates(where) { return /(?!date )('?\d\d\d\d-\d\d-\d\d'?)/.test(where); } diff --git a/packages/winnow/src/normalize-query-options/where.spec.js b/packages/winnow/src/normalize-query-options/where.spec.js index ea879e791..d5277aeb3 100644 --- a/packages/winnow/src/normalize-query-options/where.spec.js +++ b/packages/winnow/src/normalize-query-options/where.spec.js @@ -1,42 +1,49 @@ const test = require('tape'); const normalizeWhere = require('./where'); -test('normalize-options, where: undefined', t => { +test('normalize-options, where: undefined', (t) => { t.plan(1); const normalized = normalizeWhere(undefined); t.equal(normalized, undefined); }); -test('normalize-options, where: error on non-strings', t => { +test('normalize-options, where: error on non-strings', (t) => { t.plan(1); try { normalizeWhere(9999); t.fail('should have thrown'); } catch (error) { - t.equals(error.message, 'Invalid "where" parameter: must be a string if defined'); + t.equals( + error.message, + 'Invalid "where" parameter: must be a string if defined', + ); } }); -test('normalize-options, where: no changes', t => { +test('normalize-options, where: no changes', (t) => { t.plan(1); - const normalized = normalizeWhere('columns = \'test\''); - t.equal(normalized, 'columns = \'test\''); + const normalized = normalizeWhere("columns = 'test'"); + t.equal(normalized, "columns = 'test'"); }); -test('normalize-options, where: remove esri-style select-all when present', t => { +test('normalize-options, where: remove esri-style select-all when present', (t) => { t.plan(1); const normalized = normalizeWhere('1=1'); t.equal(normalized, undefined); }); -test('normalize-options, where: convert esri/sql-style dates to ISO dates', t => { +test('normalize-options, where: convert esri/sql-style dates to ISO dates', (t) => { t.plan(1); - const where = 'foo=\'bar\' AND ISSUE_DATE >= date 2017-01-05 AND ISSUE_DATE <= date 2018-01-05'; + const where = + "foo='bar' AND ISSUE_DATE >= date 2017-01-05 AND ISSUE_DATE <= date 2018-01-05"; const normalized = normalizeWhere(where); - t.equal(normalized, 'foo=\'bar\' AND ISSUE_DATE >= \'2017-01-05T00:00:00.000Z\' AND ISSUE_DATE <= \'2018-01-05T00:00:00.000Z\''); + t.equal( + normalized, + "foo='bar' AND ISSUE_DATE >= '2017-01-05T00:00:00.000Z' AND ISSUE_DATE <= '2018-01-05T00:00:00.000Z'", + ); }); diff --git a/packages/winnow/src/query/classification-query.js b/packages/winnow/src/query/classification-query.js index effac6a5b..a5d499c79 100644 --- a/packages/winnow/src/query/classification-query.js +++ b/packages/winnow/src/query/classification-query.js @@ -2,7 +2,7 @@ const standardQuery = require('./standard-query'); const calculateClassBreaks = require('../calculate-class-breaks'); const uniqueValueQuery = require('./unique-value-query'); -function classificationQuery (features, sqlstatement, options) { +function classificationQuery(features, sqlstatement, options) { const { features: filtered } = standardQuery(features, sqlstatement, options); validateQueryResult(filtered); @@ -10,7 +10,8 @@ function classificationQuery (features, sqlstatement, options) { const { breakCount, type } = classification; if (type === 'classes') { - if (breakCount <= 0) throw new Error('breakCount must be positive: ' + breakCount); + if (breakCount <= 0) + throw new Error('breakCount must be positive: ' + breakCount); return calculateClassBreaks(filtered, classification); } @@ -21,12 +22,14 @@ function classificationQuery (features, sqlstatement, options) { throw new Error(`unacceptable classification type: ${type}`); } -function validateQueryResult (features) { +function validateQueryResult(features) { if (features === undefined) { throw new Error('query results include undefined features'); } if (features.length === 0) { - throw new Error('query results in zero features; features needed in order to classify'); + throw new Error( + 'query results in zero features; features needed in order to classify', + ); } } diff --git a/packages/winnow/src/query/classification-query.spec.js b/packages/winnow/src/query/classification-query.spec.js index 6d8296d3c..dd610f904 100644 --- a/packages/winnow/src/query/classification-query.spec.js +++ b/packages/winnow/src/query/classification-query.spec.js @@ -3,20 +3,20 @@ const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './classification-query'; -test('classificationQuery, unsupported classification type', t => { +test('classificationQuery, unsupported classification type', (t) => { const standardQuerySpy = sinon.spy(function () { return { features: ['feature1', 'feature2'] }; }); const classificationQuery = proxyquire(modulePath, { - './standard-query': standardQuerySpy + './standard-query': standardQuerySpy, }); try { classificationQuery(['feature1', 'feature2', 'feature3'], 'SQL statement', { foo: 'bar', collection: {}, - classification: { } + classification: {}, }); t.fail('classificationQuery should have failed'); } catch (error) { @@ -25,26 +25,26 @@ test('classificationQuery, unsupported classification type', t => { t.deepEquals(standardQuerySpy.firstCall.args, [ ['feature1', 'feature2', 'feature3'], 'SQL statement', - { foo: 'bar', collection: {}, classification: {} } + { foo: 'bar', collection: {}, classification: {} }, ]); } t.end(); }); -test('classificationQuery, unsupported breakCount', t => { +test('classificationQuery, unsupported breakCount', (t) => { const standardQuerySpy = sinon.spy(function () { return { features: ['feature1', 'feature2'] }; }); const classificationQuery = proxyquire(modulePath, { - './standard-query': standardQuerySpy + './standard-query': standardQuerySpy, }); try { classificationQuery(['feature1', 'feature2', 'feature3'], 'SQL statement', { foo: 'bar', collection: {}, - classification: { type: 'classes', breakCount: 0 } + classification: { type: 'classes', breakCount: 0 }, }); t.fail('classificationQuery should have failed'); } catch (error) { @@ -53,13 +53,17 @@ test('classificationQuery, unsupported breakCount', t => { t.deepEquals(standardQuerySpy.firstCall.args, [ ['feature1', 'feature2', 'feature3'], 'SQL statement', - { foo: 'bar', collection: {}, classification: { type: 'classes', breakCount: 0 } } + { + foo: 'bar', + collection: {}, + classification: { type: 'classes', breakCount: 0 }, + }, ]); } t.end(); }); -test('classificationQuery, classes classification type', t => { +test('classificationQuery, classes classification type', (t) => { const standardQuerySpy = sinon.spy(function () { return { features: ['feature1', 'feature2'] }; }); @@ -70,30 +74,38 @@ test('classificationQuery, classes classification type', t => { const classificationQuery = proxyquire(modulePath, { './standard-query': standardQuerySpy, - '../calculate-class-breaks/index': calculateClassBreaksSpy + '../calculate-class-breaks/index': calculateClassBreaksSpy, }); - const result = classificationQuery(['feature1', 'feature2', 'feature3'], 'SQL statement', { - foo: 'bar', - collection: {}, - classification: { type: 'classes', breakCount: 1 } - }); + const result = classificationQuery( + ['feature1', 'feature2', 'feature3'], + 'SQL statement', + { + foo: 'bar', + collection: {}, + classification: { type: 'classes', breakCount: 1 }, + }, + ); t.deepEquals(result, 'classification results'); t.ok(standardQuerySpy.calledOnce); t.deepEquals(standardQuerySpy.firstCall.args, [ ['feature1', 'feature2', 'feature3'], 'SQL statement', - { foo: 'bar', collection: {}, classification: { type: 'classes', breakCount: 1 } } + { + foo: 'bar', + collection: {}, + classification: { type: 'classes', breakCount: 1 }, + }, ]); t.ok(calculateClassBreaksSpy.calledOnce); t.deepEquals(calculateClassBreaksSpy.firstCall.args, [ ['feature1', 'feature2'], - { type: 'classes', breakCount: 1 } + { type: 'classes', breakCount: 1 }, ]); t.end(); }); -test('classificationQuery, unique classification type', t => { +test('classificationQuery, unique classification type', (t) => { const standardQuerySpy = sinon.spy(function () { return { features: ['feature1', 'feature2'] }; }); @@ -104,22 +116,29 @@ test('classificationQuery, unique classification type', t => { const classificationQuery = proxyquire(modulePath, { './standard-query': standardQuerySpy, - './unique-value-query': uniqueValueQuerySpy + './unique-value-query': uniqueValueQuerySpy, }); - const result = classificationQuery(['feature1', 'feature2', 'feature3'], 'SQL filter statement', { - foo: 'bar', - collection: {}, - classification: { type: 'unique' } - }); + const result = classificationQuery( + ['feature1', 'feature2', 'feature3'], + 'SQL filter statement', + { + foo: 'bar', + collection: {}, + classification: { type: 'unique' }, + }, + ); t.deepEquals(result, 'unique value query result'); t.ok(standardQuerySpy.calledOnce); t.deepEquals(standardQuerySpy.firstCall.args, [ ['feature1', 'feature2', 'feature3'], 'SQL filter statement', - { foo: 'bar', collection: {}, classification: { type: 'unique' } } + { foo: 'bar', collection: {}, classification: { type: 'unique' } }, ]); t.ok(uniqueValueQuerySpy.calledOnce); - t.deepEquals(uniqueValueQuerySpy.firstCall.args, [['feature1', 'feature2'], { type: 'unique' }]); + t.deepEquals(uniqueValueQuerySpy.firstCall.args, [ + ['feature1', 'feature2'], + { type: 'unique' }, + ]); t.end(); }); diff --git a/packages/winnow/src/query/index.js b/packages/winnow/src/query/index.js index fab33a1e6..7d9482f33 100644 --- a/packages/winnow/src/query/index.js +++ b/packages/winnow/src/query/index.js @@ -1,4 +1,4 @@ module.exports = { query: require('./query'), - prepareQuery: require('./prepare-query') + prepareQuery: require('./prepare-query'), }; diff --git a/packages/winnow/src/query/normalize-query-input.js b/packages/winnow/src/query/normalize-query-input.js index 6570dd18f..76ba2f742 100644 --- a/packages/winnow/src/query/normalize-query-input.js +++ b/packages/winnow/src/query/normalize-query-input.js @@ -3,10 +3,13 @@ const Joi = require('joi'); const featureSchema = Joi.object({ geometry: Joi.object().allow(null).optional(), attributes: Joi.object().optional(), - properties: Joi.object().optional() -}).or('attributes', 'properties').required().unknown(); + properties: Joi.object().optional(), +}) + .or('attributes', 'properties') + .required() + .unknown(); -function normalizeQueryInput (input) { +function normalizeQueryInput(input) { if (isFeatureCollection(input)) { return input.features; } @@ -22,9 +25,9 @@ function normalizeQueryInput (input) { throw new Error('Could not normalize query input to feature array'); } -function isFeatureCollection (input = {}) { +function isFeatureCollection(input = {}) { const featureCollectionSchema = Joi.object({ - features: Joi.array().required() + features: Joi.array().required(), }).unknown(); const { error } = featureCollectionSchema.validate(input); @@ -32,7 +35,7 @@ function isFeatureCollection (input = {}) { if (!error && isFeatureArray(input.features)) return true; } -function isFeatureArray (input) { +function isFeatureArray(input) { if (Array.isArray(input) && input.length === 0) return true; const featureArraySchema = Joi.array().items(featureSchema).required(); @@ -41,7 +44,7 @@ function isFeatureArray (input) { if (!error) return true; } -function isFeature (input) { +function isFeature(input) { const { error } = featureSchema.validate(input); if (!error) return true; } diff --git a/packages/winnow/src/query/normalize-query-input.spec.js b/packages/winnow/src/query/normalize-query-input.spec.js index 4ddb83ea0..1747fa919 100644 --- a/packages/winnow/src/query/normalize-query-input.spec.js +++ b/packages/winnow/src/query/normalize-query-input.spec.js @@ -1,63 +1,75 @@ const test = require('tape'); const normalizeQueryInput = require('./normalize-query-input'); -test('normalizeQueryInput: invalid input should throw error', t => { - const invalidInput = [undefined, null, {}, { features: [{}] }, [{}], 'string', 1234, true]; +test('normalizeQueryInput: invalid input should throw error', (t) => { + const invalidInput = [ + undefined, + null, + {}, + { features: [{}] }, + [{}], + 'string', + 1234, + true, + ]; - invalidInput.forEach(input => { + invalidInput.forEach((input) => { try { normalizeQueryInput(input); t.fail(`should have throw error on: ${input}`); } catch (error) { - t.equals(error.message, 'Could not normalize query input to feature array'); + t.equals( + error.message, + 'Could not normalize query input to feature array', + ); } }); t.end(); }); -test('normalizeQueryInput: object with features, properties', t => { +test('normalizeQueryInput: object with features, properties', (t) => { const result = normalizeQueryInput({ features: [{ properties: {} }] }); t.deepEquals(result, [{ properties: {} }]); t.end(); }); -test('normalizeQueryInput: object with features, attributes', t => { +test('normalizeQueryInput: object with features, attributes', (t) => { const result = normalizeQueryInput({ features: [{ attributes: {} }] }); t.deepEquals(result, [{ attributes: {} }]); t.end(); }); -test('normalizeQueryInput: object with empty features array', t => { +test('normalizeQueryInput: object with empty features array', (t) => { const result = normalizeQueryInput({ features: [] }); t.deepEquals(result, []); t.end(); }); -test('normalizeQueryInput: empty array', t => { +test('normalizeQueryInput: empty array', (t) => { const result = normalizeQueryInput([]); t.deepEquals(result, []); t.end(); }); -test('normalizeQueryInput: feature array, properties', t => { +test('normalizeQueryInput: feature array, properties', (t) => { const result = normalizeQueryInput([{ properties: {} }]); t.deepEquals(result, [{ properties: {} }]); t.end(); }); -test('normalizeQueryInput: feature array, attributes', t => { +test('normalizeQueryInput: feature array, attributes', (t) => { const result = normalizeQueryInput([{ attributes: {} }]); t.deepEquals(result, [{ attributes: {} }]); t.end(); }); -test('normalizeQueryInput: feature, properties', t => { +test('normalizeQueryInput: feature, properties', (t) => { const result = normalizeQueryInput({ properties: {} }); t.deepEquals(result, [{ properties: {} }]); t.end(); }); -test('normalizeQueryInput: feature attributes', t => { +test('normalizeQueryInput: feature attributes', (t) => { const result = normalizeQueryInput({ attributes: {} }); t.deepEquals(result, [{ attributes: {} }]); t.end(); diff --git a/packages/winnow/src/query/package-features.js b/packages/winnow/src/query/package-features.js index 078ad0309..bda7d0bee 100644 --- a/packages/winnow/src/query/package-features.js +++ b/packages/winnow/src/query/package-features.js @@ -1,6 +1,9 @@ const _ = require('lodash'); -function packageFeatures (features = [], { groupBy, aggregates, collection, outputCrs } = {}) { +function packageFeatures( + features = [], + { groupBy, aggregates, collection, outputCrs } = {}, +) { if (groupBy || (!aggregates && !collection)) { return features; } @@ -14,8 +17,14 @@ function packageFeatures (features = [], { groupBy, aggregates, collection, outp } } -function packageCollection ({ features, collection, outputCrs: { wkid, wkt } = {} }) { - const outputCollection = _.chain(collection).cloneDeep().set('features', features); +function packageCollection({ + features, + collection, + outputCrs: { wkid, wkt } = {}, +}) { + const outputCollection = _.chain(collection) + .cloneDeep() + .set('features', features); if (!wkid && !wkt) { return outputCollection.value(); } diff --git a/packages/winnow/src/query/package-features.spec.js b/packages/winnow/src/query/package-features.spec.js index 34d9f7ee0..fc545cb84 100644 --- a/packages/winnow/src/query/package-features.spec.js +++ b/packages/winnow/src/query/package-features.spec.js @@ -1,25 +1,29 @@ const test = require('tape'); const packageFeatures = require('./package-features'); -test('packageFeatures: groupBy option', t => { +test('packageFeatures: groupBy option', (t) => { const result = packageFeatures(['feature1', 'feature2'], { groupBy: true }); t.deepEquals(result, ['feature1', 'feature2']); t.end(); }); -test('packageFeatures: aggregates option', t => { - const result = packageFeatures(['feature1', 'feature2'], { aggregates: true }); +test('packageFeatures: aggregates option', (t) => { + const result = packageFeatures(['feature1', 'feature2'], { + aggregates: true, + }); t.deepEquals(result, 'feature1'); t.end(); }); -test('packageFeatures: collection option', t => { - const result = packageFeatures(['feature1', 'feature2'], { collection: { foo: 'bar' } }); +test('packageFeatures: collection option', (t) => { + const result = packageFeatures(['feature1', 'feature2'], { + collection: { foo: 'bar' }, + }); t.deepEquals(result, { foo: 'bar', features: ['feature1', 'feature2'] }); t.end(); }); -test('packageFeatures: no options', t => { +test('packageFeatures: no options', (t) => { const result = packageFeatures(['feature1', 'feature2'], {}); t.deepEquals(result, ['feature1', 'feature2']); t.end(); diff --git a/packages/winnow/src/query/prepare-query.js b/packages/winnow/src/query/prepare-query.js index 466887f59..54a1d9f1e 100644 --- a/packages/winnow/src/query/prepare-query.js +++ b/packages/winnow/src/query/prepare-query.js @@ -2,7 +2,7 @@ const _ = require('lodash'); const { filterAndTransform } = require('../filter-and-transform'); const { create: createSqlStatement, - params: createSqlParams + params: createSqlParams, } = require('../sql-query-builder'); const normalizeQueryOptions = require('../normalize-query-options'); const normalizeQueryInput = require('./normalize-query-input'); @@ -25,12 +25,12 @@ module.exports = function (options) { }; }; -function prepareParamsSplicer (options) { +function prepareParamsSplicer(options) { const params = createSqlParams('$features$', options); - const featuresIndex = params.findIndex(param => { + const featuresIndex = params.findIndex((param) => { return Array.isArray(param) && param[0] === '$features$'; }); - return function setFeatures (features) { + return function setFeatures(features) { params[featuresIndex] = features; return params; }; diff --git a/packages/winnow/src/query/prepare-query.spec.js b/packages/winnow/src/query/prepare-query.spec.js index 78ae454cf..8e76a22f3 100644 --- a/packages/winnow/src/query/prepare-query.spec.js +++ b/packages/winnow/src/query/prepare-query.spec.js @@ -3,22 +3,32 @@ const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './prepare-query'; -test('Should return prepared query', t => { +test('Should return prepared query', (t) => { const compiledQuerySpy = sinon.spy(() => { return 'results'; }); - const normalizeQueryInput = sinon.spy(function () { return ['features']; }); - const normalizeQueryOptions = sinon.spy(function (options) { return options; }); + const normalizeQueryInput = sinon.spy(function () { + return ['features']; + }); + const normalizeQueryOptions = sinon.spy(function (options) { + return options; + }); const sqlQueryHelpers = sinon.spy({ - create: function () { return 'sql statement'; }, - params: function (features) { return [features]; } + create: function () { + return 'sql statement'; + }, + params: function (features) { + return [features]; + }, + }); + const packageFeatures = sinon.spy(function () { + return 'return finished query result'; }); - const packageFeatures = sinon.spy(function () { return 'return finished query result'; }); const filterAndTransform = sinon.spy({ compile: function () { return compiledQuerySpy; - } + }, }); const query = proxyquire(modulePath, { @@ -27,8 +37,8 @@ test('Should return prepared query', t => { '../sql-query-builder': sqlQueryHelpers, './package-features': packageFeatures, '../filter-and-transform': { - filterAndTransform - } + filterAndTransform, + }, }); // Get a prepared query function @@ -38,15 +48,26 @@ test('Should return prepared query', t => { t.ok(sqlQueryHelpers.create.calledOnce); t.deepEquals(sqlQueryHelpers.create.firstCall.args, [{ hello: 'world' }]); t.ok(sqlQueryHelpers.params.calledOnce); - t.deepEquals(sqlQueryHelpers.params.firstCall.args, ['$features$', { hello: 'world' }]); + t.deepEquals(sqlQueryHelpers.params.firstCall.args, [ + '$features$', + { hello: 'world' }, + ]); t.equals(typeof preparedQuery, 'function'); // Execute prepared query - const result = preparedQuery({ metadata: { foo: 'bar' }, features: ['features'] }); + const result = preparedQuery({ + metadata: { foo: 'bar' }, + features: ['features'], + }); t.ok(normalizeQueryInput.calledOnce); - t.deepEquals(normalizeQueryInput.firstCall.args, [{ metadata: { foo: 'bar' }, features: ['features'] }]); + t.deepEquals(normalizeQueryInput.firstCall.args, [ + { metadata: { foo: 'bar' }, features: ['features'] }, + ]); t.ok(packageFeatures.calledOnce); - t.deepEquals(packageFeatures.firstCall.args, ['results', { hello: 'world', collection: { metadata: { foo: 'bar' } } }]); + t.deepEquals(packageFeatures.firstCall.args, [ + 'results', + { hello: 'world', collection: { metadata: { foo: 'bar' } } }, + ]); t.equals(result, 'return finished query result'); t.ok(compiledQuerySpy.calledOnce); t.deepEquals(compiledQuerySpy.firstCall.args[0][0], '$features$'); diff --git a/packages/winnow/src/query/query.js b/packages/winnow/src/query/query.js index 6f4b8d6b9..5756eb9aa 100644 --- a/packages/winnow/src/query/query.js +++ b/packages/winnow/src/query/query.js @@ -1,31 +1,33 @@ -const { - create: createSqlStatement -} = require('../sql-query-builder'); +const { create: createSqlStatement } = require('../sql-query-builder'); const normalizeQueryOptions = require('../normalize-query-options'); const normalizeQueryInput = require('./normalize-query-input'); const classificationQuery = require('./classification-query'); const standardQuery = require('./standard-query'); module.exports = function (input, options = {}) { - const { options: normalizedOptions, features } = normalizeFeaturesAndOptions(input, options); + const { options: normalizedOptions, features } = normalizeFeaturesAndOptions( + input, + options, + ); const { aggregates, classification } = normalizedOptions; const sqlStatement = createSqlStatement(normalizedOptions); - if (classification) return classificationQuery(features, sqlStatement, normalizedOptions); + if (classification) + return classificationQuery(features, sqlStatement, normalizedOptions); return standardQuery(features, sqlStatement, { skipLimitHandling: !!aggregates, - ...normalizedOptions + ...normalizedOptions, }); }; -function normalizeFeaturesAndOptions (input, options) { +function normalizeFeaturesAndOptions(input, options) { if (isFeatureCollection(input)) { const { collection, features } = decoupleFeatureCollection(input); return { options: normalizeQueryOptions({ ...options, collection }, features), - features + features, }; } @@ -33,14 +35,14 @@ function normalizeFeaturesAndOptions (input, options) { return { options: normalizeQueryOptions(options, features), - features + features, }; } -function decoupleFeatureCollection ({ features, ...collection }) { +function decoupleFeatureCollection({ features, ...collection }) { return { collection, features }; } -function isFeatureCollection (input) { +function isFeatureCollection(input) { return !!input.features; } diff --git a/packages/winnow/src/query/query.spec.js b/packages/winnow/src/query/query.spec.js index e09f832bd..71454759e 100644 --- a/packages/winnow/src/query/query.spec.js +++ b/packages/winnow/src/query/query.spec.js @@ -3,126 +3,214 @@ const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './query'; -test('Should normalize and execute standard query on feature array', t => { +test('Should normalize and execute standard query on feature array', (t) => { const spys = sinon.spy({ - normalizeQueryInput: function () { return ['features']; }, - normalizeQueryOptions: function (options) { return options; }, + normalizeQueryInput: function () { + return ['features']; + }, + normalizeQueryOptions: function (options) { + return options; + }, sqlQueryHelpers: sinon.spy({ - create: function () { return 'sql statement'; } + create: function () { + return 'sql statement'; + }, }), - standardQuery: function () { return 'standard query result'; } + standardQuery: function () { + return 'standard query result'; + }, }); const query = proxyquire(modulePath, { './normalize-query-input': spys.normalizeQueryInput, '../normalize-query-options': spys.normalizeQueryOptions, '../sql-query-builder': spys.sqlQueryHelpers, - './standard-query': spys.standardQuery + './standard-query': spys.standardQuery, }); const result = query(['features'], { hello: 'world' }); t.ok(spys.normalizeQueryInput.calledOnce); t.deepEquals(spys.normalizeQueryInput.firstCall.args, [['features']]); t.ok(spys.normalizeQueryOptions.calledOnce); - t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [{ hello: 'world' }, ['features']]); + t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [ + { hello: 'world' }, + ['features'], + ]); t.ok(spys.sqlQueryHelpers.create.calledOnce); - t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [{ hello: 'world' }]); + t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [ + { hello: 'world' }, + ]); t.ok(spys.standardQuery.calledOnce); - t.deepEquals(spys.standardQuery.firstCall.args, [['features'], 'sql statement', { skipLimitHandling: false, hello: 'world' }] - ); + t.deepEquals(spys.standardQuery.firstCall.args, [ + ['features'], + 'sql statement', + { skipLimitHandling: false, hello: 'world' }, + ]); t.equals(result, 'standard query result'); t.end(); }); -test('Should normalize and execute standard query on collection', t => { +test('Should normalize and execute standard query on collection', (t) => { const spys = sinon.spy({ - normalizeQueryInput: function () { return ['features']; }, - normalizeQueryOptions: function (options) { return options; }, + normalizeQueryInput: function () { + return ['features']; + }, + normalizeQueryOptions: function (options) { + return options; + }, sqlQueryHelpers: sinon.spy({ - create: function () { return 'sql statement'; } + create: function () { + return 'sql statement'; + }, }), - standardQuery: function () { return 'standard query result'; } + standardQuery: function () { + return 'standard query result'; + }, }); const query = proxyquire(modulePath, { './normalize-query-input': spys.normalizeQueryInput, '../normalize-query-options': spys.normalizeQueryOptions, '../sql-query-builder': spys.sqlQueryHelpers, - './standard-query': spys.standardQuery + './standard-query': spys.standardQuery, }); - const result = query({ metadata: { foo: 'bar' }, features: ['features'] }, { hello: 'world' }); + const result = query( + { metadata: { foo: 'bar' }, features: ['features'] }, + { hello: 'world' }, + ); t.ok(spys.normalizeQueryInput.notCalled); t.ok(spys.normalizeQueryOptions.calledOnce); - t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [{ hello: 'world', collection: { metadata: { foo: 'bar' } } }, ['features']]); + t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [ + { hello: 'world', collection: { metadata: { foo: 'bar' } } }, + ['features'], + ]); t.ok(spys.sqlQueryHelpers.create.calledOnce); - t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [{ hello: 'world', collection: { metadata: { foo: 'bar' } } }]); + t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [ + { hello: 'world', collection: { metadata: { foo: 'bar' } } }, + ]); t.ok(spys.standardQuery.calledOnce); t.deepEquals(spys.standardQuery.firstCall.args, [ ['features'], 'sql statement', - { skipLimitHandling: false, hello: 'world', collection: { metadata: { foo: 'bar' } } } + { + skipLimitHandling: false, + hello: 'world', + collection: { metadata: { foo: 'bar' } }, + }, ]); t.equals(result, 'standard query result'); t.end(); }); -test('Should normalize and execute breaks-classification query', t => { +test('Should normalize and execute breaks-classification query', (t) => { const spys = sinon.spy({ - normalizeQueryInput: function () { return ['features']; }, - normalizeQueryOptions: function (options) { return options; }, + normalizeQueryInput: function () { + return ['features']; + }, + normalizeQueryOptions: function (options) { + return options; + }, sqlQueryHelpers: sinon.spy({ - create: function () { return 'sql statement'; } + create: function () { + return 'sql statement'; + }, }), - classificationQuery: function () { return 'breaks classification result'; } + classificationQuery: function () { + return 'breaks classification result'; + }, }); const query = proxyquire(modulePath, { './normalize-query-input': spys.normalizeQueryInput, '../normalize-query-options': spys.normalizeQueryOptions, '../sql-query-builder': spys.sqlQueryHelpers, - './classification-query': spys.classificationQuery + './classification-query': spys.classificationQuery, }); - const result = query({ metadata: { foo: 'bar' }, features: ['features'] }, { hello: 'world', classification: {} }); + const result = query( + { metadata: { foo: 'bar' }, features: ['features'] }, + { hello: 'world', classification: {} }, + ); t.ok(spys.normalizeQueryInput.notCalled); t.ok(spys.normalizeQueryOptions.calledOnce); - t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [{ hello: 'world', classification: {}, collection: { metadata: { foo: 'bar' } } }, ['features']]); + t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [ + { + hello: 'world', + classification: {}, + collection: { metadata: { foo: 'bar' } }, + }, + ['features'], + ]); t.ok(spys.sqlQueryHelpers.create.calledOnce); - t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [{ hello: 'world', classification: {}, collection: { metadata: { foo: 'bar' } } }]); + t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [ + { + hello: 'world', + classification: {}, + collection: { metadata: { foo: 'bar' } }, + }, + ]); t.ok(spys.classificationQuery.calledOnce); t.deepEquals(spys.classificationQuery.firstCall.args, [ ['features'], 'sql statement', - { classification: {}, hello: 'world', collection: { metadata: { foo: 'bar' } } } + { + classification: {}, + hello: 'world', + collection: { metadata: { foo: 'bar' } }, + }, ]); t.equals(result, 'breaks classification result'); t.end(); }); -test('Should normalize and execute aggregation query', t => { +test('Should normalize and execute aggregation query', (t) => { const spys = sinon.spy({ - normalizeQueryInput: function () { return ['features']; }, - normalizeQueryOptions: function (options) { return options; }, + normalizeQueryInput: function () { + return ['features']; + }, + normalizeQueryOptions: function (options) { + return options; + }, sqlQueryHelpers: sinon.spy({ - create: function () { return 'sql statement'; } + create: function () { + return 'sql statement'; + }, }), - standardQuery: function () { return 'standard query result'; } + standardQuery: function () { + return 'standard query result'; + }, }); const query = proxyquire(modulePath, { './normalize-query-input': spys.normalizeQueryInput, '../normalize-query-options': spys.normalizeQueryOptions, '../sql-query-builder': spys.sqlQueryHelpers, - './standard-query': spys.standardQuery + './standard-query': spys.standardQuery, }); - const result = query({ metadata: { foo: 'bar' }, features: ['features'] }, { hello: 'world', aggregates: {} }); + const result = query( + { metadata: { foo: 'bar' }, features: ['features'] }, + { hello: 'world', aggregates: {} }, + ); t.ok(spys.normalizeQueryInput.notCalled); t.ok(spys.normalizeQueryOptions.calledOnce); - t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [{ hello: 'world', aggregates: {}, collection: { metadata: { foo: 'bar' } } }, ['features']]); + t.deepEquals(spys.normalizeQueryOptions.firstCall.args, [ + { + hello: 'world', + aggregates: {}, + collection: { metadata: { foo: 'bar' } }, + }, + ['features'], + ]); t.ok(spys.sqlQueryHelpers.create.calledOnce); - t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [{ hello: 'world', aggregates: {}, collection: { metadata: { foo: 'bar' } } }]); + t.deepEquals(spys.sqlQueryHelpers.create.firstCall.args, [ + { + hello: 'world', + aggregates: {}, + collection: { metadata: { foo: 'bar' } }, + }, + ]); t.ok(spys.standardQuery.calledOnce); t.equals(result, 'standard query result'); t.end(); diff --git a/packages/winnow/src/query/unique-value-query.js b/packages/winnow/src/query/unique-value-query.js index f79604008..a66d60986 100644 --- a/packages/winnow/src/query/unique-value-query.js +++ b/packages/winnow/src/query/unique-value-query.js @@ -2,11 +2,13 @@ const { create: createSqlStatement } = require('../sql-query-builder'); const normalizeQueryOptions = require('../normalize-query-options'); const standardQuery = require('./standard-query'); -module.exports = function uniqueValueQuery (features, { fields } = {}) { - if (fields.length > 3) throw new Error('Cannot classify using more than three fields'); +module.exports = function uniqueValueQuery(features, { fields } = {}) { + if (fields.length > 3) + throw new Error('Cannot classify using more than three fields'); - fields.map(field => { - if (!features[0].properties[field]) throw new Error(`Unknown field: ${field}`); + fields.map((field) => { + if (!features[0].properties[field]) + throw new Error(`Unknown field: ${field}`); }); const uniqueValueOptions = { @@ -14,10 +16,10 @@ module.exports = function uniqueValueQuery (features, { fields } = {}) { { type: 'count', field: fields[0], // arbitrary field choice - name: 'count' - } + name: 'count', + }, ], - groupBy: fields + groupBy: fields, }; const options = normalizeQueryOptions(uniqueValueOptions, features); diff --git a/packages/winnow/src/query/unique-value-query.spec.js b/packages/winnow/src/query/unique-value-query.spec.js index 91a63caa2..417b384f2 100644 --- a/packages/winnow/src/query/unique-value-query.spec.js +++ b/packages/winnow/src/query/unique-value-query.spec.js @@ -3,18 +3,18 @@ const sinon = require('sinon'); const proxyquire = require('proxyquire'); const modulePath = './unique-value-query'; const uniqueValueQuery = require(modulePath); -test('uniqueValueQuery, too many fields', t => { +test('uniqueValueQuery, too many fields', (t) => { t.plan(1); const features = [ { properties: { Name: 'Oak', Trunk_Diameter: 13 } }, { properties: { Name: 'Pine', Trunk_Diameter: 7 } }, { properties: { Name: 'Oak', Trunk_Diameter: 17 } }, { properties: { Name: 'Maple', Trunk_Diameter: 25 } }, - { properties: { Name: 'Maple', Trunk_Diameter: 3 } } + { properties: { Name: 'Maple', Trunk_Diameter: 3 } }, ]; const classification = { type: 'unique', - fields: ['Name', 'Location', 'Foo', 'Bar'] + fields: ['Name', 'Location', 'Foo', 'Bar'], }; try { @@ -25,18 +25,18 @@ test('uniqueValueQuery, too many fields', t => { } }); -test('uniqueValueQuery, unknown field', t => { +test('uniqueValueQuery, unknown field', (t) => { t.plan(1); const features = [ { properties: { Name: 'Oak', Trunk_Diameter: 13 } }, { properties: { Name: 'Pine', Trunk_Diameter: 7 } }, { properties: { Name: 'Oak', Trunk_Diameter: 17 } }, { properties: { Name: 'Maple', Trunk_Diameter: 25 } }, - { properties: { Name: 'Maple', Trunk_Diameter: 3 } } + { properties: { Name: 'Maple', Trunk_Diameter: 3 } }, ]; const classification = { type: 'unique', - fields: ['Name', 'Location', 'Foo'] + fields: ['Name', 'Location', 'Foo'], }; try { @@ -47,61 +47,71 @@ test('uniqueValueQuery, unknown field', t => { } }); -test('uniqueValueQuery, one field', t => { +test('uniqueValueQuery, one field', (t) => { t.plan(3); const standardQuerySpy = sinon.spy(function () { return 'standard query result for unique values'; }); const uniqueValueQuery = proxyquire(modulePath, { - './standard-query': standardQuerySpy + './standard-query': standardQuerySpy, }); const features = [ { properties: { Name: 'Oak', Trunk_Diameter: 13 } }, { properties: { Name: 'Pine', Trunk_Diameter: 7 } }, { properties: { Name: 'Oak', Trunk_Diameter: 17 } }, { properties: { Name: 'Maple', Trunk_Diameter: 25 } }, - { properties: { Name: 'Maple', Trunk_Diameter: 3 } } + { properties: { Name: 'Maple', Trunk_Diameter: 3 } }, ]; const classification = { type: 'unique', - fields: ['Name'] + fields: ['Name'], }; const result = uniqueValueQuery(features, classification); t.equals(result, 'standard query result for unique values'); t.equals(standardQuerySpy.callCount, 1); t.deepEquals(standardQuerySpy.firstCall.args, [ - [{ - properties: { - Name: 'Oak', - Trunk_Diameter: 13 - } - }, { - properties: { - Name: 'Pine', - Trunk_Diameter: 7 - } - }, { - properties: { - Name: 'Oak', - Trunk_Diameter: 17 - } - }, { - properties: { - Name: 'Maple', - Trunk_Diameter: 25 - } - }, { - properties: { - Name: 'Maple', - Trunk_Diameter: 3 - } - }], 'SELECT COUNT(properties->`Name`) as `count`, properties->`Name` as `Name` FROM ? GROUP BY properties->`Name`', { - aggregates: [{ - type: 'count', - field: 'Name', - name: 'count' - }], + [ + { + properties: { + Name: 'Oak', + Trunk_Diameter: 13, + }, + }, + { + properties: { + Name: 'Pine', + Trunk_Diameter: 7, + }, + }, + { + properties: { + Name: 'Oak', + Trunk_Diameter: 17, + }, + }, + { + properties: { + Name: 'Maple', + Trunk_Diameter: 25, + }, + }, + { + properties: { + Name: 'Maple', + Trunk_Diameter: 3, + }, + }, + ], + 'SELECT COUNT(properties->`Name`) as `count`, properties->`Name` as `Name` FROM ? GROUP BY properties->`Name`', + { + aggregates: [ + { + type: 'count', + field: 'Name', + name: 'count', + }, + ], groupBy: ['Name'], collection: undefined, idField: null, @@ -112,80 +122,92 @@ test('uniqueValueQuery, one field', t => { order: undefined, limit: undefined, outputCrs: { - wkid: 4326 + wkid: 4326, }, inputCrs: { - wkid: 4326 + wkid: 4326, }, classification: undefined, offset: undefined, dateFields: [], skipLimitHandling: true, - objectIds: undefined - } + objectIds: undefined, + }, ]); }); -test('uniqueValueQuery, two fields', t => { +test('uniqueValueQuery, two fields', (t) => { t.plan(3); const standardQuerySpy = sinon.spy(function () { return 'standard query result for unique values'; }); const uniqueValueQuery = proxyquire(modulePath, { - './standard-query': standardQuerySpy + './standard-query': standardQuerySpy, }); const features = [ { properties: { Name: 'Oak', Location: 'Mill St', Trunk_Diameter: 13 } }, { properties: { Name: 'Pine', Location: 'Mill St', Trunk_Diameter: 7 } }, { properties: { Name: 'Oak', Location: 'Mill St', Trunk_Diameter: 17 } }, - { properties: { Name: 'Maple', Location: 'Wilson St', Trunk_Diameter: 25 } }, - { properties: { Name: 'Maple', Location: 'Wilson St', Trunk_Diameter: 3 } } + { + properties: { Name: 'Maple', Location: 'Wilson St', Trunk_Diameter: 25 }, + }, + { properties: { Name: 'Maple', Location: 'Wilson St', Trunk_Diameter: 3 } }, ]; const classification = { type: 'unique', - fields: ['Name', 'Location'] + fields: ['Name', 'Location'], }; const result = uniqueValueQuery(features, classification); t.equals(result, 'standard query result for unique values'); t.equals(standardQuerySpy.callCount, 1); t.deepEquals(standardQuerySpy.firstCall.args, [ - [{ - properties: { - Name: 'Oak', - Location: 'Mill St', - Trunk_Diameter: 13 - } - }, { - properties: { - Name: 'Pine', - Location: 'Mill St', - Trunk_Diameter: 7 - } - }, { - properties: { - Name: 'Oak', - Location: 'Mill St', - Trunk_Diameter: 17 - } - }, { - properties: { - Name: 'Maple', - Location: 'Wilson St', - Trunk_Diameter: 25 - } - }, { - properties: { - Name: 'Maple', - Location: 'Wilson St', - Trunk_Diameter: 3 - } - }], 'SELECT COUNT(properties->`Name`) as `count`, properties->`Name` as `Name`, properties->`Location` as `Location` FROM ? GROUP BY properties->`Name`, properties->`Location`', { - aggregates: [{ - type: 'count', - field: 'Name', - name: 'count' - }], + [ + { + properties: { + Name: 'Oak', + Location: 'Mill St', + Trunk_Diameter: 13, + }, + }, + { + properties: { + Name: 'Pine', + Location: 'Mill St', + Trunk_Diameter: 7, + }, + }, + { + properties: { + Name: 'Oak', + Location: 'Mill St', + Trunk_Diameter: 17, + }, + }, + { + properties: { + Name: 'Maple', + Location: 'Wilson St', + Trunk_Diameter: 25, + }, + }, + { + properties: { + Name: 'Maple', + Location: 'Wilson St', + Trunk_Diameter: 3, + }, + }, + ], + 'SELECT COUNT(properties->`Name`) as `count`, properties->`Name` as `Name`, properties->`Location` as `Location` FROM ? GROUP BY properties->`Name`, properties->`Location`', + { + aggregates: [ + { + type: 'count', + field: 'Name', + name: 'count', + }, + ], groupBy: ['Name', 'Location'], collection: undefined, idField: null, @@ -196,16 +218,16 @@ test('uniqueValueQuery, two fields', t => { order: undefined, limit: undefined, outputCrs: { - wkid: 4326 + wkid: 4326, }, inputCrs: { - wkid: 4326 + wkid: 4326, }, classification: undefined, offset: undefined, dateFields: [], skipLimitHandling: true, - objectIds: undefined - } + objectIds: undefined, + }, ]); }); diff --git a/packages/winnow/src/sql-query-builder/create-sql-params.js b/packages/winnow/src/sql-query-builder/create-sql-params.js index 041119740..3ba88ffce 100644 --- a/packages/winnow/src/sql-query-builder/create-sql-params.js +++ b/packages/winnow/src/sql-query-builder/create-sql-params.js @@ -1,13 +1,16 @@ const isDifferentCrs = require('./is-different-crs'); -function params (features, { - returnGeometry, - inputCrs, - outputCrs, - aggregates, - geometry, - geometryPrecision -} = {}) { +function params( + features, + { + returnGeometry, + inputCrs, + outputCrs, + aggregates, + geometry, + geometryPrecision, + } = {}, +) { const params = []; // NOTE: order matters here // select fragment: transform function parameters here @@ -29,16 +32,20 @@ function params (features, { return params; } -function shouldAddCrsParams ({ +function shouldAddCrsParams({ aggregates, returnGeometry, inputCrs, - outputCrs + outputCrs, } = {}) { - return !aggregates && returnGeometry !== false && isDifferentCrs(inputCrs, outputCrs); + return ( + !aggregates && + returnGeometry !== false && + isDifferentCrs(inputCrs, outputCrs) + ); } -function getCrsString ({ wkt, wkid } = {}) { +function getCrsString({ wkt, wkid } = {}) { return wkt || `EPSG:${wkid}`; } diff --git a/packages/winnow/src/sql-query-builder/create-sql-params.spec.js b/packages/winnow/src/sql-query-builder/create-sql-params.spec.js index b668290fa..ba366cff2 100644 --- a/packages/winnow/src/sql-query-builder/create-sql-params.spec.js +++ b/packages/winnow/src/sql-query-builder/create-sql-params.spec.js @@ -1,52 +1,52 @@ const test = require('tape'); const createSqlParams = require('./create-sql-params'); -test('createSqlParams: returns features if no options', t => { +test('createSqlParams: returns features if no options', (t) => { t.plan(1); const params = createSqlParams(['feature']); t.deepEquals(params, [['feature']]); }); -test('createSqlParams: returns features and geometry filter', t => { +test('createSqlParams: returns features and geometry filter', (t) => { t.plan(1); const params = createSqlParams(['feature'], { geometry: 'geom-filter' }); t.deepEquals(params, [['feature'], 'geom-filter']); }); -test('createSqlParams: returns geometry precision, features and geometry filter', t => { +test('createSqlParams: returns geometry precision, features and geometry filter', (t) => { t.plan(1); const params = createSqlParams(['feature'], { geometryPrecision: 'precision', - geometry: 'geom-filter' + geometry: 'geom-filter', }); t.deepEquals(params, ['precision', ['feature'], 'geom-filter']); }); -test('createSqlParams: returns crs, features if input/output crs different', t => { +test('createSqlParams: returns crs, features if input/output crs different', (t) => { t.plan(1); const params = createSqlParams(['feature'], { inputCrs: { wkid: 4326 }, - outputCrs: { wkid: 3857 } + outputCrs: { wkid: 3857 }, }); t.deepEquals(params, ['EPSG:4326', 'EPSG:3857', ['feature']]); }); -test('createSqlParams: does not return crs, if returnGeometry===false', t => { +test('createSqlParams: does not return crs, if returnGeometry===false', (t) => { t.plan(1); const params = createSqlParams(['feature'], { returnGeometry: false, inputCrs: { wkid: 4326 }, - outputCrs: { wkid: 3857 } + outputCrs: { wkid: 3857 }, }); t.deepEquals(params, [['feature']]); }); -test('createSqlParams: does not return crs, if aggregates defined', t => { +test('createSqlParams: does not return crs, if aggregates defined', (t) => { t.plan(1); const params = createSqlParams(['feature'], { aggregates: true, inputCrs: { wkid: 4326 }, - outputCrs: { wkid: 3857 } + outputCrs: { wkid: 3857 }, }); t.deepEquals(params, [['feature']]); }); diff --git a/packages/winnow/src/sql-query-builder/create-sql-string.js b/packages/winnow/src/sql-query-builder/create-sql-string.js index 5c4a5f8ef..bde1ee50a 100644 --- a/packages/winnow/src/sql-query-builder/create-sql-string.js +++ b/packages/winnow/src/sql-query-builder/create-sql-string.js @@ -3,9 +3,12 @@ const createSelectSql = require('./select'); const createOrderByClause = require('./order-by'); const createGroupByClause = require('./group-by'); -function create (options = {}) { +function create(options = {}) { const select = createSelectSql(options); - const where = options.objectIds || options.where || options.geometry ? ` WHERE ${SqlWhereBuilder.create(options)}` : ''; + const where = + options.objectIds || options.where || options.geometry + ? ` WHERE ${SqlWhereBuilder.create(options)}` + : ''; const orderBy = createOrderByClause(options); const groupBy = createGroupByClause(options); const limit = options.limit ? ` LIMIT ${options.limit}` : ''; diff --git a/packages/winnow/src/sql-query-builder/create-sql-string.spec.js b/packages/winnow/src/sql-query-builder/create-sql-string.spec.js index 0f8d50980..7d3d00b03 100644 --- a/packages/winnow/src/sql-query-builder/create-sql-string.spec.js +++ b/packages/winnow/src/sql-query-builder/create-sql-string.spec.js @@ -5,7 +5,7 @@ const proxyquire = require('proxyquire'); const whereSpy = { create: sinon.spy(function () { return '"substring"'; - }) + }), }; const selectSpy = sinon.spy(function () { @@ -31,14 +31,17 @@ const createSqlString = proxyquire('./create-sql-string', { './where-builder': whereSpy, './select': selectSpy, './order-by': orderBySpy, - './group-by': groupBySpy + './group-by': groupBySpy, }); -test('createSqlString: with no options', t => { +test('createSqlString: with no options', (t) => { t.plan(9); testCleanup(); const sqlString = createSqlString(); - t.equals(sqlString, 'SELECT "substring" GROUP BY "substring" ORDER BY "substring"'); + t.equals( + sqlString, + 'SELECT "substring" GROUP BY "substring" ORDER BY "substring"', + ); t.equals(selectSpy.callCount, 1); t.equals(whereSpy.create.callCount, 0); t.equals(groupBySpy.callCount, 1); @@ -50,27 +53,33 @@ test('createSqlString: with no options', t => { testCleanup(); }); -test('createSqlString: with objectIds option', t => { +test('createSqlString: with objectIds option', (t) => { t.plan(9); testCleanup(); const sqlString = createSqlString({ objectIds: [2] }); - t.equals(sqlString, 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"'); + t.equals( + sqlString, + 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"', + ); t.equals(selectSpy.callCount, 1); t.equals(whereSpy.create.callCount, 1); t.equals(groupBySpy.callCount, 1); t.equals(orderBySpy.callCount, 1); - t.deepEquals(selectSpy.firstCall.args, [{ objectIds: [ 2 ] }]); - t.deepEquals(whereSpy.create.firstCall.args, [{ objectIds: [ 2 ] }]); - t.deepEquals(groupBySpy.firstCall.args, [{ objectIds: [ 2 ] }]); - t.deepEquals(orderBySpy.firstCall.args, [{ objectIds: [ 2 ] }]); + t.deepEquals(selectSpy.firstCall.args, [{ objectIds: [2] }]); + t.deepEquals(whereSpy.create.firstCall.args, [{ objectIds: [2] }]); + t.deepEquals(groupBySpy.firstCall.args, [{ objectIds: [2] }]); + t.deepEquals(orderBySpy.firstCall.args, [{ objectIds: [2] }]); testCleanup(); }); -test('createSqlString: with where option', t => { +test('createSqlString: with where option', (t) => { t.plan(9); testCleanup(); const sqlString = createSqlString({ where: '1=1' }); - t.equals(sqlString, 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"'); + t.equals( + sqlString, + 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"', + ); t.equals(selectSpy.callCount, 1); t.equals(whereSpy.create.callCount, 1); t.equals(groupBySpy.callCount, 1); @@ -82,46 +91,58 @@ test('createSqlString: with where option', t => { testCleanup(); }); -test('createSqlString: with geometry option', t => { +test('createSqlString: with geometry option', (t) => { t.plan(9); testCleanup(); - const sqlString = createSqlString({ geometry: [0,0,0,0] }); - t.equals(sqlString, 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"'); + const sqlString = createSqlString({ geometry: [0, 0, 0, 0] }); + t.equals( + sqlString, + 'SELECT "substring" WHERE "substring" GROUP BY "substring" ORDER BY "substring"', + ); t.equals(selectSpy.callCount, 1); t.equals(whereSpy.create.callCount, 1); t.equals(groupBySpy.callCount, 1); t.equals(orderBySpy.callCount, 1); - t.deepEquals(selectSpy.firstCall.args, [{ geometry: [0,0,0,0] }]); - t.deepEquals(whereSpy.create.firstCall.args, [{ geometry: [0,0,0,0] }]); - t.deepEquals(groupBySpy.firstCall.args, [{ geometry: [0,0,0,0] }]); - t.deepEquals(orderBySpy.firstCall.args, [{ geometry: [0,0,0,0] }]); + t.deepEquals(selectSpy.firstCall.args, [{ geometry: [0, 0, 0, 0] }]); + t.deepEquals(whereSpy.create.firstCall.args, [{ geometry: [0, 0, 0, 0] }]); + t.deepEquals(groupBySpy.firstCall.args, [{ geometry: [0, 0, 0, 0] }]); + t.deepEquals(orderBySpy.firstCall.args, [{ geometry: [0, 0, 0, 0] }]); testCleanup(); }); -test('createSqlString: with limit and offset options', t => { +test('createSqlString: with limit and offset options', (t) => { t.plan(9); testCleanup(); const sqlString = createSqlString({ limit: 10, - offset: 20 + offset: 20, }); - t.equals(sqlString, 'SELECT "substring" GROUP BY "substring" ORDER BY "substring" LIMIT 10 OFFSET 20'); + t.equals( + sqlString, + 'SELECT "substring" GROUP BY "substring" ORDER BY "substring" LIMIT 10 OFFSET 20', + ); t.equals(selectSpy.callCount, 1); t.equals(whereSpy.create.callCount, 0); t.equals(groupBySpy.callCount, 1); t.equals(orderBySpy.callCount, 1); - t.deepEquals(selectSpy.firstCall.args, [{ - limit: 10, - offset: 20 - }]); + t.deepEquals(selectSpy.firstCall.args, [ + { + limit: 10, + offset: 20, + }, + ]); t.deepEquals(whereSpy.create.notCalled, true); - t.deepEquals(groupBySpy.firstCall.args, [{ - limit: 10, - offset: 20 - }]); - t.deepEquals(orderBySpy.firstCall.args, [{ - limit: 10, - offset: 20 - }]); + t.deepEquals(groupBySpy.firstCall.args, [ + { + limit: 10, + offset: 20, + }, + ]); + t.deepEquals(orderBySpy.firstCall.args, [ + { + limit: 10, + offset: 20, + }, + ]); testCleanup(); }); diff --git a/packages/winnow/src/sql-query-builder/group-by.js b/packages/winnow/src/sql-query-builder/group-by.js index ef6e1eac2..cf5d2b071 100644 --- a/packages/winnow/src/sql-query-builder/group-by.js +++ b/packages/winnow/src/sql-query-builder/group-by.js @@ -1,9 +1,11 @@ -function createGroupByClause ({ groupBy, esri } = {}) { +function createGroupByClause({ groupBy, esri } = {}) { if (!groupBy) return ''; const selector = esri ? 'attributes' : 'properties'; - const groups = groupBy.map(group => { - return `${selector}->\`${group}\``; - }).join(', '); + const groups = groupBy + .map((group) => { + return `${selector}->\`${group}\``; + }) + .join(', '); return ` GROUP BY ${groups}`; } diff --git a/packages/winnow/src/sql-query-builder/group-by.spec.js b/packages/winnow/src/sql-query-builder/group-by.spec.js index c04414dc1..169c52bc0 100644 --- a/packages/winnow/src/sql-query-builder/group-by.spec.js +++ b/packages/winnow/src/sql-query-builder/group-by.spec.js @@ -1,26 +1,29 @@ const test = require('tape'); const createGroupByClause = require('./group-by'); -test('createGroupByClause: returns empty string if no options', t => { +test('createGroupByClause: returns empty string if no options', (t) => { t.plan(1); const groupByClause = createGroupByClause(); t.equals(groupByClause, ''); }); -test('createGroupByClause: returns empty string if empty options', t => { +test('createGroupByClause: returns empty string if empty options', (t) => { t.plan(1); const groupByClause = createGroupByClause({}); t.equals(groupByClause, ''); }); -test('createGroupByClause: returns groupBy clause', t => { +test('createGroupByClause: returns groupBy clause', (t) => { t.plan(1); const groupByClause = createGroupByClause({ groupBy: ['foo', 'bar'] }); t.equals(groupByClause, ' GROUP BY properties->`foo`, properties->`bar`'); }); -test('createGroupByClause: returns groupBy clause for esri JSON', t => { +test('createGroupByClause: returns groupBy clause for esri JSON', (t) => { t.plan(1); - const groupByClause = createGroupByClause({ esri: true, groupBy: ['foo', 'bar'] }); + const groupByClause = createGroupByClause({ + esri: true, + groupBy: ['foo', 'bar'], + }); t.equals(groupByClause, ' GROUP BY attributes->`foo`, attributes->`bar`'); }); diff --git a/packages/winnow/src/sql-query-builder/index.js b/packages/winnow/src/sql-query-builder/index.js index 002a8e398..96982c3e2 100644 --- a/packages/winnow/src/sql-query-builder/index.js +++ b/packages/winnow/src/sql-query-builder/index.js @@ -1,4 +1,4 @@ module.exports = { create: require('./create-sql-string'), - params: require('./create-sql-params') + params: require('./create-sql-params'), }; diff --git a/packages/winnow/src/sql-query-builder/is-different-crs.js b/packages/winnow/src/sql-query-builder/is-different-crs.js index 29775bb6e..c55a39156 100644 --- a/packages/winnow/src/sql-query-builder/is-different-crs.js +++ b/packages/winnow/src/sql-query-builder/is-different-crs.js @@ -1,3 +1,3 @@ -module.exports = function isDifferentCrs (inputCrs = {}, outputCrs = {}) { +module.exports = function isDifferentCrs(inputCrs = {}, outputCrs = {}) { return inputCrs.wkid !== outputCrs.wkid || inputCrs.wkt !== outputCrs.wkt; }; diff --git a/packages/winnow/src/sql-query-builder/is-different-crs.spec.js b/packages/winnow/src/sql-query-builder/is-different-crs.spec.js index c6bf67230..fde28bcbd 100644 --- a/packages/winnow/src/sql-query-builder/is-different-crs.spec.js +++ b/packages/winnow/src/sql-query-builder/is-different-crs.spec.js @@ -1,43 +1,43 @@ const test = require('tape'); const isDifferentCrs = require('./is-different-crs'); -test('isDifferentCrs: different WKIDs', t => { +test('isDifferentCrs: different WKIDs', (t) => { t.plan(1); const result = isDifferentCrs({ wkid: 4326 }, { wkid: 3857 }); t.equals(result, true); }); -test('isDifferentCrs: same WKIDs', t => { +test('isDifferentCrs: same WKIDs', (t) => { t.plan(1); const result = isDifferentCrs({ wkid: 4326 }, { wkid: 4326 }); t.equals(result, false); }); -test('isDifferentCrs: different WKTs', t => { +test('isDifferentCrs: different WKTs', (t) => { t.plan(1); const result = isDifferentCrs({ wkt: 'wkt-string' }, { wkt: 'foodbar' }); t.equals(result, true); }); -test('isDifferentCrs: same WKTs', t => { +test('isDifferentCrs: same WKTs', (t) => { t.plan(1); const result = isDifferentCrs({ wkt: 'wkt-string' }, { wkt: 'wkt-string' }); t.equals(result, false); }); -test('isDifferentCrs: different WKTs', t => { +test('isDifferentCrs: different WKTs', (t) => { t.plan(1); const result = isDifferentCrs({ wkt: 'wkt-string' }, { wkt: 'foodbar' }); t.equals(result, true); }); -test('isDifferentCrs: mixed wkt and wkid', t => { +test('isDifferentCrs: mixed wkt and wkid', (t) => { t.plan(1); const result = isDifferentCrs({ wkid: 4326 }, { wkt: 'wkt-string' }); t.equals(result, true); }); -test('isDifferentCrs: mixed wkt and wkid', t => { +test('isDifferentCrs: mixed wkt and wkid', (t) => { t.plan(1); const result = isDifferentCrs({ wkt: 'wkt-string' }, { wkid: 4326 }); t.equals(result, true); diff --git a/packages/winnow/src/sql-query-builder/order-by.js b/packages/winnow/src/sql-query-builder/order-by.js index d1747d10c..e98ef72a7 100644 --- a/packages/winnow/src/sql-query-builder/order-by.js +++ b/packages/winnow/src/sql-query-builder/order-by.js @@ -1,24 +1,29 @@ -function createOrderByClause (options = {}) { +function createOrderByClause(options = {}) { const { order: orderByArray, esri, aggregates } = options; if (!orderByArray) return ''; const selector = esri ? 'attributes' : 'properties'; - const orderByClause = orderByArray.map(orderBy => { - const [field, direction = 'ASC'] = orderBy.split(' '); - if (shouldFormatForAggregationQuery(field, aggregates)) { - return `\`${field}\` ${direction.toUpperCase()}`; - } - return `${selector}->\`${field}\` ${direction.toUpperCase()}`; - }).join(', '); + const orderByClause = orderByArray + .map((orderBy) => { + const [field, direction = 'ASC'] = orderBy.split(' '); + if (shouldFormatForAggregationQuery(field, aggregates)) { + return `\`${field}\` ${direction.toUpperCase()}`; + } + return `${selector}->\`${field}\` ${direction.toUpperCase()}`; + }) + .join(', '); return ` ORDER BY ${orderByClause}`; } -function shouldFormatForAggregationQuery (field, aggregations) { - return aggregations && aggregations.some(({ name }) => { - return field === name; - }); +function shouldFormatForAggregationQuery(field, aggregations) { + return ( + aggregations && + aggregations.some(({ name }) => { + return field === name; + }) + ); } module.exports = createOrderByClause; diff --git a/packages/winnow/src/sql-query-builder/order-by.spec.js b/packages/winnow/src/sql-query-builder/order-by.spec.js index 8acd29995..66516fb1b 100644 --- a/packages/winnow/src/sql-query-builder/order-by.spec.js +++ b/packages/winnow/src/sql-query-builder/order-by.spec.js @@ -1,44 +1,67 @@ const test = require('tape'); const createOrderByClause = require('./order-by'); -test('createOrderByClause: returns empty string if no options', t => { +test('createOrderByClause: returns empty string if no options', (t) => { t.plan(1); const orderByClause = createOrderByClause(); t.equals(orderByClause, ''); }); -test('createOrderByClause: returns empty string if empty options', t => { +test('createOrderByClause: returns empty string if empty options', (t) => { t.plan(1); const orderByClause = createOrderByClause({}); t.equals(orderByClause, ''); }); -test('createOrderByClause: returns orderBy clause with default direction', t => { +test('createOrderByClause: returns orderBy clause with default direction', (t) => { t.plan(1); const orderByClause = createOrderByClause({ order: ['foo', 'bar'] }); - t.equals(orderByClause, ' ORDER BY properties->`foo` ASC, properties->`bar` ASC'); + t.equals( + orderByClause, + ' ORDER BY properties->`foo` ASC, properties->`bar` ASC', + ); }); -test('createOrderByClause: returns orderBy clause for esri JSON', t => { +test('createOrderByClause: returns orderBy clause for esri JSON', (t) => { t.plan(1); - const orderByClause = createOrderByClause({ esri: true, order: ['foo', 'bar'] }); - t.equals(orderByClause, ' ORDER BY attributes->`foo` ASC, attributes->`bar` ASC'); + const orderByClause = createOrderByClause({ + esri: true, + order: ['foo', 'bar'], + }); + t.equals( + orderByClause, + ' ORDER BY attributes->`foo` ASC, attributes->`bar` ASC', + ); }); -test('createOrderByClause: returns orderBy clause with directions ', t => { +test('createOrderByClause: returns orderBy clause with directions ', (t) => { t.plan(1); - const orderByClause = createOrderByClause({ order: ['foo DESC', 'bar DESC'] }); - t.equals(orderByClause, ' ORDER BY properties->`foo` DESC, properties->`bar` DESC'); + const orderByClause = createOrderByClause({ + order: ['foo DESC', 'bar DESC'], + }); + t.equals( + orderByClause, + ' ORDER BY properties->`foo` DESC, properties->`bar` DESC', + ); }); -test('createOrderByClause: returns orderBy clause formated for aggregation select', t => { +test('createOrderByClause: returns orderBy clause formated for aggregation select', (t) => { t.plan(1); - const orderByClause = createOrderByClause({ order: ['foo DESC', 'bar DESC'], aggregates: [{ name: 'foo' }] }); + const orderByClause = createOrderByClause({ + order: ['foo DESC', 'bar DESC'], + aggregates: [{ name: 'foo' }], + }); t.equals(orderByClause, ' ORDER BY `foo` DESC, properties->`bar` DESC'); }); -test('createOrderByClause: returns orderBy clause formated for aggregation select', t => { +test('createOrderByClause: returns orderBy clause formated for aggregation select', (t) => { t.plan(1); - const orderByClause = createOrderByClause({ order: ['foo DESC', 'bar DESC'], aggregates: [{ name: 'hello' }] }); - t.equals(orderByClause, ' ORDER BY properties->`foo` DESC, properties->`bar` DESC'); + const orderByClause = createOrderByClause({ + order: ['foo DESC', 'bar DESC'], + aggregates: [{ name: 'hello' }], + }); + t.equals( + orderByClause, + ' ORDER BY properties->`foo` DESC, properties->`bar` DESC', + ); }); diff --git a/packages/winnow/src/sql-query-builder/select/aggregation-select.js b/packages/winnow/src/sql-query-builder/select/aggregation-select.js index 7ead36c20..e587a9c23 100644 --- a/packages/winnow/src/sql-query-builder/select/aggregation-select.js +++ b/packages/winnow/src/sql-query-builder/select/aggregation-select.js @@ -1,4 +1,4 @@ -function createAggregationSelect (aggregates, groupBy, esri) { +function createAggregationSelect(aggregates, groupBy, esri) { const selector = esri ? 'attributes' : 'properties'; const select = aggregates.reduce((sql, agg) => { let func; @@ -13,10 +13,12 @@ function createAggregationSelect (aggregates, groupBy, esri) { else return `${select.slice(0, -1)} FROM ?`; } -function addGroupBy (select, groupBy, selector) { - const fields = groupBy.reduce((fragment, group) => { - return `${fragment} ${selector}->\`${group}\` as \`${group}\`,`; - }, '').slice(0, -1); +function addGroupBy(select, groupBy, selector) { + const fields = groupBy + .reduce((fragment, group) => { + return `${fragment} ${selector}->\`${group}\` as \`${group}\`,`; + }, '') + .slice(0, -1); return `${select.slice(0, -1)}, ${fields} FROM ? `; } diff --git a/packages/winnow/src/sql-query-builder/select/fields-select-fragment.js b/packages/winnow/src/sql-query-builder/select/fields-select-fragment.js index 39c988a9a..b8cea2fb0 100644 --- a/packages/winnow/src/sql-query-builder/select/fields-select-fragment.js +++ b/packages/winnow/src/sql-query-builder/select/fields-select-fragment.js @@ -1,4 +1,4 @@ -function createFieldsSelectFragment (options = {}) { +function createFieldsSelectFragment(options = {}) { const { fields, toEsri } = options; if (toEsri) { @@ -8,7 +8,7 @@ function createFieldsSelectFragment (options = {}) { return selectFieldsAsGeoJson(fields); } -function selectFieldsAsEsriJson (options) { +function selectFieldsAsEsriJson(options) { const { fields, dateFields = [], returnIdsOnly, idField = null } = options; const delimitedDateFields = dateFields.join(','); const includeIdField = shouldIncludeIdField({ returnIdsOnly, fields }); @@ -18,12 +18,12 @@ function selectFieldsAsEsriJson (options) { return `toEsriAttributes(properties, geometry, "${delimitedDateFields}", "${includeIdField}", "${idField}") as attributes`; } -function shouldIncludeIdField ({ returnIdsOnly, fields }) { +function shouldIncludeIdField({ returnIdsOnly, fields }) { if (returnIdsOnly || !fields || fields.includes('OBJECTID')) return true; return false; } -function selectFieldsAsGeoJson (fields) { +function selectFieldsAsGeoJson(fields) { if (fields) { return `selectFields(properties, "${fields.join(',')}") as properties`; } diff --git a/packages/winnow/src/sql-query-builder/select/fields-select-fragment.spec.js b/packages/winnow/src/sql-query-builder/select/fields-select-fragment.spec.js index 36a755433..1e33a313e 100644 --- a/packages/winnow/src/sql-query-builder/select/fields-select-fragment.spec.js +++ b/packages/winnow/src/sql-query-builder/select/fields-select-fragment.spec.js @@ -1,119 +1,149 @@ const test = require('tape'); const createFieldsSelectFragment = require('./fields-select-fragment'); -test('createFieldsSelectFragment: no specification', t => { +test('createFieldsSelectFragment: no specification', (t) => { const fieldsFragment = createFieldsSelectFragment({}); t.equal(fieldsFragment, 'type, properties as properties'); t.end(); }); -test('createFieldsSelectFragment: fields option', t => { +test('createFieldsSelectFragment: fields option', (t) => { const fieldsFragment = createFieldsSelectFragment({ - fields: ['foo', 'bar'] + fields: ['foo', 'bar'], }); t.equal(fieldsFragment, 'selectFields(properties, "foo,bar") as properties'); t.end(); }); -test('createFieldsSelectFragment: fields and dateFields options', t => { +test('createFieldsSelectFragment: fields and dateFields options', (t) => { const fieldsFragment = createFieldsSelectFragment({ fields: ['foo', 'bar', 'hello', 'world'], - dateFields: ['foo', 'hello'] + dateFields: ['foo', 'hello'], }); - t.equal(fieldsFragment, 'selectFields(properties, "foo,bar,hello,world") as properties'); + t.equal( + fieldsFragment, + 'selectFields(properties, "foo,bar,hello,world") as properties', + ); t.end(); }); -test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly options', t => { +test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly options', (t) => { const fieldsFragment = createFieldsSelectFragment({ fields: ['foo', 'bar', 'hello', 'world'], dateFields: ['foo', 'hello'], - returnIdsOnly: true + returnIdsOnly: true, }); - t.equal(fieldsFragment, 'selectFields(properties, "foo,bar,hello,world") as properties'); + t.equal( + fieldsFragment, + 'selectFields(properties, "foo,bar,hello,world") as properties', + ); t.end(); }); -test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly, idField options', t => { +test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly, idField options', (t) => { const fieldsFragment = createFieldsSelectFragment({ fields: ['foo', 'bar', 'hello', 'world'], dateFields: ['foo', 'hello'], returnIdsOnly: true, - idField: 'bar' + idField: 'bar', }); - t.equal(fieldsFragment, 'selectFields(properties, "foo,bar,hello,world") as properties'); + t.equal( + fieldsFragment, + 'selectFields(properties, "foo,bar,hello,world") as properties', + ); t.end(); }); -test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly, idField as OBJECTID options', t => { +test('createFieldsSelectFragment: fields, dateFields, returnIdsOnly, idField as OBJECTID options', (t) => { const fieldsFragment = createFieldsSelectFragment({ fields: ['foo', 'OBJECTID', 'hello', 'world'], dateFields: ['foo', 'hello'], returnIdsOnly: true, - idField: 'OBJECTID' + idField: 'OBJECTID', }); - t.equal(fieldsFragment, 'selectFields(properties, "foo,OBJECTID,hello,world") as properties'); + t.equal( + fieldsFragment, + 'selectFields(properties, "foo,OBJECTID,hello,world") as properties', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri option', t => { +test('createFieldsSelectFragment: toEsri option', (t) => { const fieldsFragment = createFieldsSelectFragment({ - toEsri: true + toEsri: true, }); - t.equal(fieldsFragment, 'toEsriAttributes(properties, geometry, "", "true", "null") as attributes'); + t.equal( + fieldsFragment, + 'toEsriAttributes(properties, geometry, "", "true", "null") as attributes', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri and fields options', t => { +test('createFieldsSelectFragment: toEsri and fields options', (t) => { const fieldsFragment = createFieldsSelectFragment({ toEsri: true, - fields: ['foo', 'bar'] + fields: ['foo', 'bar'], }); - t.equal(fieldsFragment, 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar", "", "false", "null") as attributes'); + t.equal( + fieldsFragment, + 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar", "", "false", "null") as attributes', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri, fields, dateFields options', t => { +test('createFieldsSelectFragment: toEsri, fields, dateFields options', (t) => { const fieldsFragment = createFieldsSelectFragment({ toEsri: true, fields: ['foo', 'bar', 'hello', 'world'], - dateFields: ['foo', 'hello'] + dateFields: ['foo', 'hello'], }); - t.equal(fieldsFragment, 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "false", "null") as attributes'); + t.equal( + fieldsFragment, + 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "false", "null") as attributes', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly options', t => { +test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly options', (t) => { const fieldsFragment = createFieldsSelectFragment({ toEsri: true, fields: ['foo', 'bar', 'hello', 'world'], dateFields: ['foo', 'hello'], - returnIdsOnly: true + returnIdsOnly: true, }); - t.equal(fieldsFragment, 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "true", "null") as attributes'); + t.equal( + fieldsFragment, + 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "true", "null") as attributes', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly, idField options', t => { +test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly, idField options', (t) => { const fieldsFragment = createFieldsSelectFragment({ toEsri: true, fields: ['foo', 'bar', 'hello', 'world'], dateFields: ['foo', 'hello'], returnIdsOnly: true, - idField: 'bar' + idField: 'bar', }); - t.equal(fieldsFragment, 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "true", "bar") as attributes'); + t.equal( + fieldsFragment, + 'selectFieldsToEsriAttributes(properties, geometry, "foo,bar,hello,world", "foo,hello", "true", "bar") as attributes', + ); t.end(); }); -test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly, idField as OBJECTID options', t => { +test('createFieldsSelectFragment: toEsri, fields, dateFields, returnIdsOnly, idField as OBJECTID options', (t) => { const fieldsFragment = createFieldsSelectFragment({ toEsri: true, fields: ['foo', 'OBJECTID', 'hello', 'world'], dateFields: ['foo', 'hello'], returnIdsOnly: true, - idField: 'OBJECTID' + idField: 'OBJECTID', }); - t.equal(fieldsFragment, 'selectFieldsToEsriAttributes(properties, geometry, "foo,OBJECTID,hello,world", "foo,hello", "true", "OBJECTID") as attributes'); + t.equal( + fieldsFragment, + 'selectFieldsToEsriAttributes(properties, geometry, "foo,OBJECTID,hello,world", "foo,hello", "true", "OBJECTID") as attributes', + ); t.end(); }); diff --git a/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.js b/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.js index ffbd5d412..107b4ce87 100644 --- a/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.js +++ b/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.js @@ -1,5 +1,10 @@ const isDifferentCrs = require('../is-different-crs'); -function createGeometrySelectFragment ({ inputCrs, outputCrs, geometryPrecision, toEsri } = {}) { +function createGeometrySelectFragment({ + inputCrs, + outputCrs, + geometryPrecision, + toEsri, +} = {}) { const geometryFunctions = []; if (isDifferentCrs(inputCrs, outputCrs)) { geometryFunctions.push('project(~~,?,?)'); @@ -17,11 +22,14 @@ function createGeometrySelectFragment ({ inputCrs, outputCrs, geometryPrecision, return 'geometry'; } - const inlineGeometryFunctions = geometryFunctions.reduce(nestGeometryFunctions, ''); + const inlineGeometryFunctions = geometryFunctions.reduce( + nestGeometryFunctions, + '', + ); return `${inlineGeometryFunctions} as geometry`; } -function nestGeometryFunctions (nestedFunctionString, functionString, index) { +function nestGeometryFunctions(nestedFunctionString, functionString, index) { if (index === 0) { return functionString.replace('~~', 'geometry'); } diff --git a/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.spec.js b/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.spec.js index ab7569b24..7a816ecdb 100644 --- a/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.spec.js +++ b/packages/winnow/src/sql-query-builder/select/geometry-select-fragment.spec.js @@ -1,56 +1,83 @@ const test = require('tape'); const createGeometrySelectFragment = require('./geometry-select-fragment'); -test('createGeometryFragment: no options', t => { +test('createGeometryFragment: no options', (t) => { const geometryFragment = createGeometrySelectFragment(); t.equal(geometryFragment, 'geometry'); t.end(); }); -test('createGeometryFragment: empty options', t => { +test('createGeometryFragment: empty options', (t) => { const geometryFragment = createGeometrySelectFragment({}); t.equal(geometryFragment, 'geometry'); t.end(); }); -test('createGeometryFragment: same input/output CRS option', t => { - const geometryFragment = createGeometrySelectFragment({ inputCrs: { wkid: 3857 }, outputCrs: { wkid: 3857 } }); +test('createGeometryFragment: same input/output CRS option', (t) => { + const geometryFragment = createGeometrySelectFragment({ + inputCrs: { wkid: 3857 }, + outputCrs: { wkid: 3857 }, + }); t.equal(geometryFragment, 'geometry'); t.end(); }); -test('createGeometryFragment: different input/output CRS option', t => { - const geometryFragment = createGeometrySelectFragment({ inputCrs: { wkid: 4326 }, outputCrs: { wkid: 3857 } }); +test('createGeometryFragment: different input/output CRS option', (t) => { + const geometryFragment = createGeometrySelectFragment({ + inputCrs: { wkid: 4326 }, + outputCrs: { wkid: 3857 }, + }); t.equal(geometryFragment, 'project(geometry,?,?) as geometry'); t.end(); }); -test('createGeometryFragment: geometryPrecision option', t => { - const geometryFragment = createGeometrySelectFragment({ geometryPrecision: 1 }); +test('createGeometryFragment: geometryPrecision option', (t) => { + const geometryFragment = createGeometrySelectFragment({ + geometryPrecision: 1, + }); t.equal(geometryFragment, 'reducePrecision(geometry,?) as geometry'); t.end(); }); -test('createGeometryFragment: toEsri option', t => { +test('createGeometryFragment: toEsri option', (t) => { const geometryFragment = createGeometrySelectFragment({ toEsri: true }); t.equal(geometryFragment, 'esriGeometry(geometry) as geometry'); t.end(); }); -test('createGeometryFragment: different input/output CRS, and geometryPrecision options', t => { - const geometryFragment = createGeometrySelectFragment({ inputCrs: { wkid: 4326 }, outputCrs: { wkid: 3857 }, geometryPrecision: 1 }); - t.equal(geometryFragment, 'reducePrecision(project(geometry,?,?),?) as geometry'); +test('createGeometryFragment: different input/output CRS, and geometryPrecision options', (t) => { + const geometryFragment = createGeometrySelectFragment({ + inputCrs: { wkid: 4326 }, + outputCrs: { wkid: 3857 }, + geometryPrecision: 1, + }); + t.equal( + geometryFragment, + 'reducePrecision(project(geometry,?,?),?) as geometry', + ); t.end(); }); -test('createGeometryFragment: different input/output CRS, geometryPrecision, and toEsri options', t => { - const geometryFragment = createGeometrySelectFragment({ inputCrs: { wkid: 4326 }, outputCrs: { wkid: 3857 }, geometryPrecision: 1, toEsri: true }); - t.equal(geometryFragment, 'esriGeometry(reducePrecision(project(geometry,?,?),?)) as geometry'); +test('createGeometryFragment: different input/output CRS, geometryPrecision, and toEsri options', (t) => { + const geometryFragment = createGeometrySelectFragment({ + inputCrs: { wkid: 4326 }, + outputCrs: { wkid: 3857 }, + geometryPrecision: 1, + toEsri: true, + }); + t.equal( + geometryFragment, + 'esriGeometry(reducePrecision(project(geometry,?,?),?)) as geometry', + ); t.end(); }); -test('createGeometryFragment: different input/output CRS, and toEsri options', t => { - const geometryFragment = createGeometrySelectFragment({ inputCrs: { wkid: 4326 }, outputCrs: { wkid: 3857 }, toEsri: true }); +test('createGeometryFragment: different input/output CRS, and toEsri options', (t) => { + const geometryFragment = createGeometrySelectFragment({ + inputCrs: { wkid: 4326 }, + outputCrs: { wkid: 3857 }, + toEsri: true, + }); t.equal(geometryFragment, 'esriGeometry(project(geometry,?,?)) as geometry'); t.end(); }); diff --git a/packages/winnow/src/sql-query-builder/select/index.js b/packages/winnow/src/sql-query-builder/select/index.js index ff037c4b3..c8bca8321 100644 --- a/packages/winnow/src/sql-query-builder/select/index.js +++ b/packages/winnow/src/sql-query-builder/select/index.js @@ -2,24 +2,28 @@ const createAggregationSelect = require('./aggregation-select'); const createGeometrySelectFragment = require('./geometry-select-fragment'); const createFieldsSelectFragment = require('./fields-select-fragment'); -function createSelectSql (options = {}) { +function createSelectSql(options = {}) { if (options.aggregates) { - return createAggregationSelect(options.aggregates, options.groupBy, options.esri); + return createAggregationSelect( + options.aggregates, + options.groupBy, + options.esri, + ); } return createStandardSelect(options); } -function createStandardSelect (options) { +function createStandardSelect(options) { const select = options.distinct ? 'SELECT DISTINCT' : 'SELECT'; const fieldsList = createFieldsSelectFragment(options); if (options.returnGeometry === false) { - return (`${select} ${fieldsList} FROM ?`); + return `${select} ${fieldsList} FROM ?`; } - return (`${select} ${fieldsList}, ${createGeometrySelectFragment(options)} FROM ?`); + return `${select} ${fieldsList}, ${createGeometrySelectFragment(options)} FROM ?`; } module.exports = createSelectSql; diff --git a/packages/winnow/src/sql-query-builder/select/index.spec.js b/packages/winnow/src/sql-query-builder/select/index.spec.js index 818355aa4..fb245d085 100644 --- a/packages/winnow/src/sql-query-builder/select/index.spec.js +++ b/packages/winnow/src/sql-query-builder/select/index.spec.js @@ -4,7 +4,7 @@ const proxyquire = require('proxyquire'); const createSelectSql = proxyquire('./', { './aggregation-select': sinon.stub().returns('aggregation SELECT'), './geometry-select-fragment': sinon.stub().returns('geometry fragment'), - './fields-select-fragment': sinon.stub().returns('fields fragment') + './fields-select-fragment': sinon.stub().returns('fields fragment'), }); test('createSelectSql: no options', async (spec) => { @@ -35,4 +35,4 @@ test('createSelectSql: distinct:true option', async (spec) => { spec.plan(1); const result = createSelectSql({ distinct: true, returnGeometry: false }); spec.equals(result, 'SELECT DISTINCT fields fragment FROM ?'); -}); \ No newline at end of file +}); diff --git a/packages/winnow/src/sql-query-builder/where-builder/index.js b/packages/winnow/src/sql-query-builder/where-builder/index.js index ee8ad54ac..829eb02ab 100644 --- a/packages/winnow/src/sql-query-builder/where-builder/index.js +++ b/packages/winnow/src/sql-query-builder/where-builder/index.js @@ -1,7 +1,7 @@ const { InvalidWhereParameterError } = require('../../errors'); const convertSqlWhereToJsonWhere = require('./to-json-where'); -const timestampCastRegex = /(TIMESTAMP|DATE) '([^']*)'/gi; // eslint-disable-line +const timestampCastRegex = /(TIMESTAMP|DATE) '([^']*)'/gi; const timestampWithoutZoneRegex = /^\d{4}-\d{2}-\d{2} {0,1}\d{0,2}:{0,1}\d{0,2}:{0,1}\d{0,2}$/; @@ -137,10 +137,10 @@ class WhereBuilder { } #addObjectIdsFilter() { - const inValues = this.#options.objectIds.map(val => { + const inValues = this.#options.objectIds.map((val) => { return isNaN(val) ? `'${val}'` : val; }); - + const objectIdFilter = `${ this.#options.idField || 'OBJECTID' } IN (${inValues.join(',')})`; @@ -166,7 +166,7 @@ class WhereBuilder { this.#where = this.#where .replace( fieldFirstObjectIdPredicateRegex, - `hashedObjectIdComparator($1, geometry, $3, '$2')=true`, // eslint-disable-line + `hashedObjectIdComparator($1, geometry, $3, '$2')=true`, ) .replace( objectidInPredicateRegex, @@ -218,14 +218,14 @@ function normalizeTimestamp(timestamp) { } function isBeginningOfValueDefinition(char, insideSingleQuotes) { - return insideSingleQuotes === false && char === "'"; // eslint-disable-line + return insideSingleQuotes === false && char === "'"; } function isSingleQuoteEscapeChar(char, next, prev, insideSingleQuotes) { return ( insideSingleQuotes === true && - char === "'" && // eslint-disable-line - next === "'" && // eslint-disable-line + char === "'" && + next === "'" && prev !== SINGLE_QUOTE_ESCAPE ); } @@ -233,7 +233,7 @@ function isSingleQuoteEscapeChar(char, next, prev, insideSingleQuotes) { function isEndOfValueDefinition(char, lastTwoChars, insideSingleQuotes) { return ( insideSingleQuotes === true && - char === `'` && // eslint-disable-line + char === `'` && lastTwoChars !== `${SINGLE_QUOTE_ESCAPE}'` ); } diff --git a/packages/winnow/src/sql-query-builder/where-builder/index.spec.js b/packages/winnow/src/sql-query-builder/where-builder/index.spec.js index 826393c67..8aa1eb681 100644 --- a/packages/winnow/src/sql-query-builder/where-builder/index.spec.js +++ b/packages/winnow/src/sql-query-builder/where-builder/index.spec.js @@ -1,4 +1,3 @@ -/* eslint-disable quotes */ const test = require('tape'); const WhereBuilder = require('.'); @@ -26,16 +25,16 @@ test('WhereBuilder.create: objectIds param, numeric', (t) => { t.plan(1); const whereClause = WhereBuilder.create({ objectIds: [1, 2], - idField: 'OBJECTID' + idField: 'OBJECTID', }); - t.equals(whereClause, "properties->`OBJECTID` IN (1, 2 )"); + t.equals(whereClause, 'properties->`OBJECTID` IN (1, 2 )'); }); test('WhereBuilder.create: objectIds param, string', (t) => { t.plan(1); const whereClause = WhereBuilder.create({ objectIds: ['abc', 'xyz'], - idField: 'OBJECTID' + idField: 'OBJECTID', }); t.equals(whereClause, "properties->`OBJECTID` IN ('abc', 'xyz' )"); }); @@ -45,9 +44,12 @@ test('WhereBuilder.create: where param and objectIds param', (t) => { const whereClause = WhereBuilder.create({ where: "color='red'", objectIds: [1, 2], - idField: 'OBJECTID' + idField: 'OBJECTID', }); - t.equals(whereClause, "properties->`color` = 'red' AND properties->`OBJECTID` IN (1, 2 )"); + t.equals( + whereClause, + "properties->`color` = 'red' AND properties->`OBJECTID` IN (1, 2 )", + ); }); test('WhereBuilder.create: returns where clause with geometry predicate', (t) => { @@ -76,7 +78,7 @@ test('WhereBuilder.create: transform a predicate with OBJECTID and no metadata f const whereClause = WhereBuilder.create({ where: 'OBJECTID=1234' }); t.equals( whereClause, - "hashedObjectIdComparator(properties, geometry, 1234, '=')=true", // eslint-disable-line + "hashedObjectIdComparator(properties, geometry, 1234, '=')=true", ); }); @@ -86,7 +88,7 @@ test('WhereBuilder.create: transform a predicate with OBJECTID IN (1234)', (t) = const whereClause = WhereBuilder.create({ objectIds: [1234, 4567] }); t.equals( whereClause, - "hashedObjectIdComparator(properties, geometry, '1234,4567', 'IN')=true", // eslint-disable-line + "hashedObjectIdComparator(properties, geometry, '1234,4567', 'IN')=true", ); }); @@ -100,7 +102,7 @@ test('WhereBuilder.create: transform a predicate with OBJECTID and no metadata f const whereClause = WhereBuilder.create(options); t.equals( whereClause, - "hashedObjectIdComparator(attributes, geometry, 1234, '=')=true", // eslint-disable-line + "hashedObjectIdComparator(attributes, geometry, 1234, '=')=true", ); }); @@ -114,7 +116,7 @@ test('WhereBuilder.create: transform an inverse predicate with OBJECTID and no m const whereClause = WhereBuilder.create(options); t.equals( whereClause, - "hashedObjectIdComparator(attributes, geometry, 1234, '<=')=true", // eslint-disable-line + "hashedObjectIdComparator(attributes, geometry, 1234, '<=')=true", ); }); @@ -143,7 +145,7 @@ test('WhereBuilder.create: handle escaped single quotes', (t) => { const whereClause = WhereBuilder.create({ where: "Street_Name = 'GRAND''S STREET''S'", }); - t.equals(whereClause, "properties->`Street_Name` = 'GRAND\\'S STREET\\'S'"); // eslint-disable-line + t.equals(whereClause, "properties->`Street_Name` = 'GRAND\\'S STREET\\'S'"); }); test('WhereBuilder.create: handle TIMESTAMP cast', (t) => { diff --git a/packages/winnow/src/sql-query-builder/where-builder/to-json-where.js b/packages/winnow/src/sql-query-builder/where-builder/to-json-where.js index 96c44e8f6..bca0cba2c 100644 --- a/packages/winnow/src/sql-query-builder/where-builder/to-json-where.js +++ b/packages/winnow/src/sql-query-builder/where-builder/to-json-where.js @@ -10,7 +10,7 @@ const { InvalidWhereParameterError } = require('../../errors'); function translateSqlWhere(where, { esri, esriFields } = {}) { try { const ast = parser.parse(`SELECT * FROM koop WHERE ${where}`); - + // TODO: move this to options normalization const codedValueLookup = getCodedValueMap(esriFields); @@ -23,7 +23,6 @@ function translateSqlWhere(where, { esri, esriFields } = {}) { } } - /** * Traverse a SQL AST; modify for JSON querying and return * @param {object} node AST node @@ -42,7 +41,9 @@ function traverse(node, options) { } if (node.type === 'String') { - return shouldHandleAsColumn(node) ? handleColumn(node, options) : handleValue(node, options); + return shouldHandleAsColumn(node) + ? handleColumn(node, options) + : handleValue(node, options); } if (['Number', 'Boolean'].includes(node.type)) { @@ -68,7 +69,7 @@ function handleColumn(node, options) { : `properties->\`${node.value}\``; } -function shouldHandleAsColumn (node) { +function shouldHandleAsColumn(node) { return /^"([^"]*)"$/.test(node.value); } @@ -79,7 +80,7 @@ function handleValue(node, { codedValueLookup }) { } } -function trackTargetColumn (node) { +function trackTargetColumn(node) { if (node?.left?.type === 'Identifier') { node.right.targetColumnName = node.left.value; } @@ -91,7 +92,9 @@ function trackTargetColumn (node) { // distribute target column to any downstream nodes; required for IN if (node.targetColumnName) { if (Array.isArray(node.value)) { - node.value.forEach((child) => child.targetColumnName = node.targetColumnName); + node.value.forEach( + (child) => (child.targetColumnName = node.targetColumnName), + ); } if (node.left) { @@ -105,17 +108,17 @@ function trackTargetColumn (node) { function getCodedValueMap(featureLayerFieldDefintions = []) { return featureLayerFieldDefintions - .filter(fieldDefintion => fieldDefintion?.domain?.type === 'codedValue') + .filter((fieldDefintion) => fieldDefintion?.domain?.type === 'codedValue') .map(({ name, domain: { codedValues } }) => { return { name, codedValues: codedValues.reduce((accumulator, { code, name }) => { accumulator[code] = name; return accumulator; - }, {}) + }, {}), }; }) - .reduce((accumulator, {name, codedValues}) => { + .reduce((accumulator, { name, codedValues }) => { accumulator[name] = codedValues; return accumulator; }, {}); diff --git a/packages/winnow/src/sql-query-builder/where-builder/to-json-where.spec.js b/packages/winnow/src/sql-query-builder/where-builder/to-json-where.spec.js index a4a8ebfa8..2015782f7 100644 --- a/packages/winnow/src/sql-query-builder/where-builder/to-json-where.spec.js +++ b/packages/winnow/src/sql-query-builder/where-builder/to-json-where.spec.js @@ -1,4 +1,3 @@ -/* eslint-disable quotes */ const test = require('tape'); const translateSqlWhere = require('./to-json-where'); @@ -98,10 +97,9 @@ test('toJsonWhere: handle IN list of strings', (t) => { t.plan(1); const whereFragment = translateSqlWhere(`foo IN ('foo', 'bar')`); - t.equals(whereFragment, 'properties->`foo` IN (\'foo\', \'bar\' )'); + t.equals(whereFragment, "properties->`foo` IN ('foo', 'bar' )"); }); - test('toJsonWhere: handle IS NULL', (t) => { t.plan(1); diff --git a/packages/winnow/test/integration/aggregate.spec.js b/packages/winnow/test/integration/aggregate.spec.js index a9d41b8cb..6e5a0c60f 100644 --- a/packages/winnow/test/integration/aggregate.spec.js +++ b/packages/winnow/test/integration/aggregate.spec.js @@ -4,30 +4,30 @@ const winnow = require('../../src'); const features = require('./fixtures/trees.json'); const snowFeatures = require('./fixtures/snow.json'); -test('Get a sum', t => { +test('Get a sum', (t) => { t.plan(1); const options = { aggregates: [ { type: 'sum', - field: 'Trunk_Diameter' - } - ] + field: 'Trunk_Diameter', + }, + ], }; const results = winnow.query(features, options); t.equal(results.sum_Trunk_Diameter, 263); }); -test('Use a group by', t => { +test('Use a group by', (t) => { t.plan(3); const options = { aggregates: [ { type: 'avg', - field: 'Trunk_Diameter' - } + field: 'Trunk_Diameter', + }, ], - groupBy: 'Genus' + groupBy: 'Genus', }; const results = winnow.query(features, options); t.equal(results.length, 6); @@ -35,33 +35,33 @@ test('Use a group by', t => { t.ok(results[0].avg_Trunk_Diameter); }); -test('Use an order and a group by', t => { +test('Use an order and a group by', (t) => { t.plan(2); const options = { aggregates: [ { type: 'avg', - field: 'Trunk_Diameter' - } + field: 'Trunk_Diameter', + }, ], groupBy: 'Genus', - order: 'avg_Trunk_Diameter DESC' + order: 'avg_Trunk_Diameter DESC', }; const results = winnow.query(features, options); t.equal(results.length, 6); t.equal(results[0].avg_Trunk_Diameter, 13.166666666666666); }); -test('Use a group by esri style', t => { +test('Use a group by esri style', (t) => { t.plan(3); const options = { outStatistics: [ { statisticType: 'avg', - onStatisticField: 'Trunk_Diameter' - } + onStatisticField: 'Trunk_Diameter', + }, ], - groupByFieldsForStatistics: ['Genus'] + groupByFieldsForStatistics: ['Genus'], }; const results = winnow.query(features, options); t.equal(results.length, 6); @@ -69,16 +69,16 @@ test('Use a group by esri style', t => { t.ok(results[0].avg_Trunk_Diameter); }); -test('Use multiple group bys', t => { +test('Use multiple group bys', (t) => { t.plan(4); const options = { aggregates: [ { type: 'avg', - field: 'Trunk_Diameter' - } + field: 'Trunk_Diameter', + }, ], - groupBy: ['Genus', 'Common_Name'] + groupBy: ['Genus', 'Common_Name'], }; const results = winnow.query(features, options); t.equal(results.length, 7); @@ -87,16 +87,16 @@ test('Use multiple group bys', t => { t.ok(results[0].avg_Trunk_Diameter); }); -test('Use multiple group bys ESRI style', t => { +test('Use multiple group bys ESRI style', (t) => { t.plan(4); const options = { aggregates: [ { type: 'avg', - field: 'Trunk_Diameter' - } + field: 'Trunk_Diameter', + }, ], - groupByFieldsForStatistics: 'Genus,Common_Name' + groupByFieldsForStatistics: 'Genus,Common_Name', }; const results = winnow.query(features, options); t.equal(results.length, 7); @@ -105,17 +105,17 @@ test('Use multiple group bys ESRI style', t => { t.ok(results[0].avg_Trunk_Diameter); }); -test('Use a group by with a where clause', t => { +test('Use a group by with a where clause', (t) => { t.plan(3); const options = { aggregates: [ { type: 'avg', - field: 'Trunk_Diameter' - } + field: 'Trunk_Diameter', + }, ], where: 'Trunk_Diameter > 10', - groupBy: 'Genus' + groupBy: 'Genus', }; const results = winnow.query(features, options); t.equal(results.length, 3); @@ -123,156 +123,156 @@ test('Use a group by with a where clause', t => { t.ok(results[0].avg_Trunk_Diameter); }); -test('Get a named aggregate', t => { +test('Get a named aggregate', (t) => { t.plan(1); const options = { aggregates: [ { type: 'sum', field: 'Trunk_Diameter', - name: 'total_diameter' - } - ] + name: 'total_diameter', + }, + ], }; const results = winnow.query(features, options); t.equal(results.total_diameter, 263); }); -test('Get an aggregate on a field with a space', t => { +test('Get an aggregate on a field with a space', (t) => { t.plan(1); const options = { aggregates: [ { type: 'sum', - field: 'total precip' - } - ] + field: 'total precip', + }, + ], }; const results = winnow.query(snowFeatures, options); t.equal(results.sum_total_precip, 5.300000000000001); }); -test('Get an aggregate on a field with a /', t => { +test('Get an aggregate on a field with a /', (t) => { t.plan(1); const options = { aggregates: [ { type: 'count', field: 'Test/Field', - name: 'Test/Field_COUNT' - } - ] + name: 'Test/Field_COUNT', + }, + ], }; const results = winnow.query(features, options); t.equal(results['Test/Field_COUNT'], 2); }); -test.skip('Get the variance of a field', t => { +test.skip('Get the variance of a field', (t) => { t.plan(1); const options = { aggregates: [ { type: 'var', - field: 'total precip' - } - ] + field: 'total precip', + }, + ], }; const results = winnow.query(snowFeatures, options); t.equal(results.var_total_precip.toFixed(15), 0.02571923076923076); }); -test('Get an aggregate with a where clause', t => { +test('Get an aggregate with a where clause', (t) => { t.plan(1); const options = { aggregates: [ { type: 'sum', field: 'Trunk_Diameter', - name: 'total_diameter' - } + name: 'total_diameter', + }, ], - where: 'Trunk_Diameter > 10' + where: 'Trunk_Diameter > 10', }; const results = winnow.query(features, options); t.equal(results.total_diameter, 207); }); -test('Get multiple aggregates', t => { +test('Get multiple aggregates', (t) => { t.plan(2); const options = { aggregates: [ { type: 'sum', field: 'Trunk_Diameter', - name: 'total_diameter' + name: 'total_diameter', }, { type: 'max', field: 'Trunk_Diameter', - name: 'max_diameter' - } - ] + name: 'max_diameter', + }, + ], }; const results = winnow.query(features, options); t.equal(results.total_diameter, 263); t.equal(results.max_diameter, 27); }); -test('Get multiple aggregates specified in the esri way', t => { +test('Get multiple aggregates specified in the esri way', (t) => { t.plan(2); const options = { outStatistics: [ { statisticType: 'sum', onStatisticField: 'Trunk_Diameter', - outStatisticFieldName: 'total_diameter' + outStatisticFieldName: 'total_diameter', }, { statisticType: 'max', onStatisticField: 'Trunk_Diameter', - outStatisticFieldName: 'max_diameter' - } - ] + outStatisticFieldName: 'max_diameter', + }, + ], }; const results = winnow.query(features, options); t.equal(results.total_diameter, 263); t.equal(results.max_diameter, 27); }); -test('Get multiple aggregates with a where clause', t => { +test('Get multiple aggregates with a where clause', (t) => { t.plan(2); const options = { aggregates: [ { type: 'sum', field: 'Trunk_Diameter', - name: 'total_diameter' + name: 'total_diameter', }, { type: 'max', field: 'Trunk_Diameter', - name: 'max_diameter' - } + name: 'max_diameter', + }, ], - where: 'Trunk_Diameter > 10' + where: 'Trunk_Diameter > 10', }; const results = winnow.query(features, options); t.equal(results.total_diameter, 207); t.equal(results.max_diameter, 27); }); -test('ignore projection when getting an aggregate', t => { +test('ignore projection when getting an aggregate', (t) => { t.plan(3); const options = { aggregates: [ { type: 'count', field: 'Trunk_Diameter', - name: 'count_trunk_Diameter' - } + name: 'count_trunk_Diameter', + }, ], groupBy: 'Trunk_Diameter', - outSR: 102100 + outSR: 102100, }; const results = winnow.query(features, options); t.equal(results[0].count_trunk_Diameter, 2); @@ -280,18 +280,18 @@ test('ignore projection when getting an aggregate', t => { t.ok(results[0].count_trunk_Diameter); }); -test('ignore projection when getting an aggregate specified in the esri way', t => { +test('ignore projection when getting an aggregate specified in the esri way', (t) => { t.plan(3); const options = { outStatistics: [ { statisticType: 'count', onStatisticField: 'Trunk_Diameter', - outStatisticFieldName: 'count_trunk_Diameter' - } + outStatisticFieldName: 'count_trunk_Diameter', + }, ], groupByFieldsForStatistics: ['Trunk_Diameter'], - outSR: 102100 + outSR: 102100, }; const results = winnow.query(features, options); t.equal(results[0].count_trunk_Diameter, 2); diff --git a/packages/winnow/test/integration/classification.spec.js b/packages/winnow/test/integration/classification.spec.js index 25f858eb3..74a6b122e 100644 --- a/packages/winnow/test/integration/classification.spec.js +++ b/packages/winnow/test/integration/classification.spec.js @@ -9,7 +9,7 @@ const geoServicesClassBreaks = require('./fixtures/classification/geoServicesCla const geoServicesUniqueValue = require('./fixtures/classification/geoServicesUniqueValue.json'); /* class breaks */ -test('create class breaks', t => { +test('create class breaks', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); const results = winnow.query(treesSubset, options); @@ -21,7 +21,7 @@ test('create class breaks', t => { t.end(); }); -test('create class breaks without where clause', t => { +test('create class breaks without where clause', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); delete options.where; @@ -34,7 +34,7 @@ test('create class breaks without where clause', t => { t.end(); }); -test('change class break count', t => { +test('change class break count', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.breakCount = 9; @@ -47,7 +47,7 @@ test('change class break count', t => { t.end(); }); -test('change classification field', t => { +test('change classification field', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.field = 'House_Number'; @@ -60,7 +60,7 @@ test('change classification field', t => { t.end(); }); -test('classify using natural breaks', t => { +test('classify using natural breaks', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.method = 'naturalBreaks'; @@ -72,7 +72,7 @@ test('classify using natural breaks', t => { t.deepEqual(results[6], [13, 13]); }); -test('classify using quantile', t => { +test('classify using quantile', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.method = 'quantile'; @@ -84,7 +84,7 @@ test('classify using quantile', t => { t.deepEqual(results[6], [13, 13]); }); -test('classify using standard deviation', t => { +test('classify using standard deviation', (t) => { t.plan(6); const options = _.cloneDeep(classBreaks); options.classification.method = 'stddev'; @@ -99,7 +99,7 @@ test('classify using standard deviation', t => { t.deepEqual(results[14], [35.773262, 40.257608]); }); -test('normalize by field', t => { +test('normalize by field', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.field = 'House_Number'; @@ -113,7 +113,7 @@ test('normalize by field', t => { t.deepEqual(results[6], [628.4065934065934, 726.6666666666666]); }); -test('normalize by log', t => { +test('normalize by log', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.normType = 'log'; @@ -125,7 +125,7 @@ test('normalize by log', t => { t.deepEqual(results[6], [0.9548085876915742, 1.1139433523068367]); }); -test('normalize by total', t => { +test('normalize by total', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); options.classification.normType = 'percent'; @@ -137,37 +137,45 @@ test('normalize by total', t => { t.deepEqual(results[6], [10.51212938005391, 12.264150943396226]); }); -test('unrecognized classification field', t => { +test('unrecognized classification field', (t) => { t.plan(1); const options = _.cloneDeep(classBreaks); options.classification.field = 'UNRECOGNIZED_FIELD'; - t.throws(function () { winnow.query(treesSubset, options); }); + t.throws(function () { + winnow.query(treesSubset, options); + }); }); -test('unacceptable classification field', t => { +test('unacceptable classification field', (t) => { t.plan(1); const options = _.cloneDeep(classBreaks); options.classification.field = 'Common_Name'; - t.throws(function () { winnow.query(treesSubset, options); }); + t.throws(function () { + winnow.query(treesSubset, options); + }); }); -test('unacceptable classification method', t => { +test('unacceptable classification method', (t) => { t.plan(1); const options = _.cloneDeep(classBreaks); options.classification.method = 'invalidMethod'; - t.throws(function () { winnow.query(treesSubset, options); }); + t.throws(function () { + winnow.query(treesSubset, options); + }); }); -test('handle unacceptable field with different value types', t => { +test('handle unacceptable field with different value types', (t) => { t.plan(1); const options = _.cloneDeep(classBreaks); options.where = 'House_Number>200'; const data = _.cloneDeep(treesSubset); data.features[2].properties.Trunk_Diameter = 'Invalid Value'; - t.throws(function () { winnow.query(data, options); }); + t.throws(function () { + winnow.query(data, options); + }); }); -test('remove null values during classification', t => { +test('remove null values during classification', (t) => { t.plan(5); const options = _.cloneDeep(classBreaks); const data = _.cloneDeep(treesSubset); @@ -185,7 +193,7 @@ test('remove null values during classification', t => { }); /* unique values */ -test('create unique values', t => { +test('create unique values', (t) => { t.plan(5); const options = _.cloneDeep(uniqueValue); const results = winnow.query(treesSubset, options); @@ -197,27 +205,30 @@ test('create unique values', t => { t.end(); }); -test('add unique values', t => { +test('add unique values', (t) => { t.plan(6); const options = _.cloneDeep(uniqueValue); const ammendedtrees = _.cloneDeep(treesSubset); - ammendedtrees.features.push({ - type: 'Feature', - properties: { - OBJECTID: 99998, - Common_Name: 'SOUTHERN MAGNOLIA', - Genus: 'MAGNOLIA', - Trunk_Diameter: 10 - } - }, { - type: 'Feature', - properties: { - OBJECTID: 99999, - Common_Name: 'SOUTHERN NEW_GENUS', - Genus: 'NEW_GENUS', - Trunk_Diameter: 11 - } - }); + ammendedtrees.features.push( + { + type: 'Feature', + properties: { + OBJECTID: 99998, + Common_Name: 'SOUTHERN MAGNOLIA', + Genus: 'MAGNOLIA', + Trunk_Diameter: 10, + }, + }, + { + type: 'Feature', + properties: { + OBJECTID: 99999, + Common_Name: 'SOUTHERN NEW_GENUS', + Genus: 'NEW_GENUS', + Trunk_Diameter: 11, + }, + }, + ); const results = winnow.query(ammendedtrees, options); t.equal(Array.isArray(results), true); t.equal(typeof results === 'object', true); @@ -228,7 +239,7 @@ test('add unique values', t => { t.end(); }); -test('change unique value field', t => { +test('change unique value field', (t) => { t.plan(5); const options = _.cloneDeep(uniqueValue); options.classification.fields[0] = 'Common_Name'; @@ -241,50 +252,62 @@ test('change unique value field', t => { t.end(); }); -test('create unique values with multiple unique fields', t => { +test('create unique values with multiple unique fields', (t) => { t.plan(6); const options = { classification: { type: 'unique', fields: ['EmployeeID', 'ShipperID'], - fieldDelimiter: ', ' + fieldDelimiter: ', ', }, where: 'OBJECTID<11310', - f: 'pjson' + f: 'pjson', }; const results = winnow.query(multipleUnique, options); t.equal(Array.isArray(results), true); t.equal(typeof results === 'object', true); t.equal(results.length, 6); t.deepEqual(results[0], { count: 1, EmployeeID: 'John', ShipperID: 'Marc' }); - t.deepEqual(results[3], { count: 2, EmployeeID: 'Leeroy', ShipperID: 'Marc' }); - t.deepEqual(results[5], { count: 1, EmployeeID: 'Leeroy', ShipperID: 'Eric' }); + t.deepEqual(results[3], { + count: 2, + EmployeeID: 'Leeroy', + ShipperID: 'Marc', + }); + t.deepEqual(results[5], { + count: 1, + EmployeeID: 'Leeroy', + ShipperID: 'Eric', + }); t.end(); }); -test('cannot create unique values with more than three fields', t => { +test('cannot create unique values with more than three fields', (t) => { t.plan(1); const options = { classification: { type: 'unique', fields: ['EmployeeID', 'ShipperID', 'Department', 'Date'], - fieldDelimiter: ', ' + fieldDelimiter: ', ', }, where: 'OBJECTID<11310', - f: 'pjson' + f: 'pjson', }; - t.throws(function () { winnow.query(treesSubset, options); }); + t.throws(function () { + winnow.query(treesSubset, options); + }); }); -test('unacceptable classification field', t => { +test('unacceptable classification field', (t) => { t.plan(1); const options = _.cloneDeep(uniqueValue); options.classification.fields[0] = 'Unacceptable Field'; - t.throws(function () { winnow.query(multipleUnique, options); }); + t.throws(function () { + winnow.query(multipleUnique, options); + }); }); /* geoservices fixtures */ -test('create class breaks using geoservices fixture', t => { +test('create class breaks using geoservices fixture', (t) => { t.plan(5); const options = _.cloneDeep(geoServicesClassBreaks); const results = winnow.query(treesSubset, options); @@ -296,7 +319,7 @@ test('create class breaks using geoservices fixture', t => { t.end(); }); -test('modify class breaks using geoservices fixture', t => { +test('modify class breaks using geoservices fixture', (t) => { const options = _.cloneDeep(geoServicesClassBreaks); options.classificationDef.classificationMethod = 'esriClassifyNaturalBreaks'; options.classificationDef.breakCount = 9; @@ -311,7 +334,7 @@ test('modify class breaks using geoservices fixture', t => { t.end(); }); -test('create unique values using geoservices fixture', t => { +test('create unique values using geoservices fixture', (t) => { t.plan(5); const options = _.cloneDeep(geoServicesUniqueValue); const results = winnow.query(treesSubset, options); @@ -323,7 +346,7 @@ test('create unique values using geoservices fixture', t => { t.end(); }); -test('modify unique values using geoservices fixture', t => { +test('modify unique values using geoservices fixture', (t) => { t.plan(5); const options = _.cloneDeep(geoServicesUniqueValue); options.classificationDef.uniqueValueFields[0] = 'Common_Name'; diff --git a/packages/winnow/test/integration/fields.spec.js b/packages/winnow/test/integration/fields.spec.js index eca6f16a9..04f546c70 100644 --- a/packages/winnow/test/integration/fields.spec.js +++ b/packages/winnow/test/integration/fields.spec.js @@ -3,33 +3,33 @@ const test = require('tape'); const winnow = require('../..'); const features = require('./fixtures/trees.json').features; -test('Select a single field', t => { +test('Select a single field', (t) => { t.plan(1); const options = { fields: ['Trunk_Diameter'], - limit: 1 + limit: 1, }; const filtered = winnow.query(features, options); const fields = Object.keys(filtered[0].properties); t.equal(fields[0], 'Trunk_Diameter'); }); -test('Select a single field with string input', t => { +test('Select a single field with string input', (t) => { t.plan(1); const options = { fields: 'Trunk_Diameter', - limit: 1 + limit: 1, }; const filtered = winnow.query(features, options); const fields = Object.keys(filtered[0].properties); t.equal(fields[0], 'Trunk_Diameter'); }); -test('Select multiple fields', t => { +test('Select multiple fields', (t) => { t.plan(2); const options = { fields: ['Trunk_Diameter', 'Genus'], - limit: 1 + limit: 1, }; const filtered = winnow.query(features, options); const fields = Object.keys(filtered[0].properties); diff --git a/packages/winnow/test/integration/filter.spec.js b/packages/winnow/test/integration/filter.spec.js index 38c2a0678..5ec5cd10a 100644 --- a/packages/winnow/test/integration/filter.spec.js +++ b/packages/winnow/test/integration/filter.spec.js @@ -4,7 +4,7 @@ const winnow = require('../..'); test('With a where option', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", }; run('trees', options, 8, t); }); @@ -19,7 +19,7 @@ test('With a where options 1=1', (t) => { test('With a where option with multiple statements', (t) => { const options = { where: - 'Genus like \'%Quercus%\' AND Street_Name = \'CLAREMONT\' AND House_Number < 600 AND Trunk_Diameter = 9', + "Genus like '%Quercus%' AND Street_Name = 'CLAREMONT' AND House_Number < 600 AND Trunk_Diameter = 9", }; run('trees', options, 1, t); }); @@ -27,14 +27,14 @@ test('With a where option with multiple statements', (t) => { test('With a where option with multiple statements with appended 1=1', (t) => { const options = { where: - 'Genus like \'%Quercus%\' AND Street_Name = \'CLAREMONT\' AND House_Number < 600 AND Trunk_Diameter = 9 AND 1=1', + "Genus like '%Quercus%' AND Street_Name = 'CLAREMONT' AND House_Number < 600 AND Trunk_Diameter = 9 AND 1=1", }; run('trees', options, 1, t); }); test('With a field that has been uppercased', (t) => { const options = { - where: 'UPPER(Genus) like \'%Quercus%\'', + where: "UPPER(Genus) like '%Quercus%'", }; t.plan(1); const fixtures = _.cloneDeep(require('./fixtures/trees.json')); @@ -46,7 +46,7 @@ test('With a field that has been uppercased', (t) => { test('With the toEsri option', (t) => { const options = { toEsri: true, - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", }; run('trees', options, 8, t); }); @@ -71,7 +71,7 @@ test('With a field with a space', (t) => { test('With esri json', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", esri: true, }; run('esri', options, 8, t); @@ -80,14 +80,14 @@ test('With esri json', (t) => { test('With multiple like clauses', (t) => { const options = { where: - 'Genus like \'%Quercus%\' AND Common_Name like \'%Live Oak%\' AND Street_Type like \'%ST%\'', + "Genus like '%Quercus%' AND Common_Name like '%Live Oak%' AND Street_Type like '%ST%'", }; run('trees', options, 5, t); }); test('With an in parameter', (t) => { const options = { - where: 'Genus IN (\'QUERCUS\', \'EUGENIA\')', + where: "Genus IN ('QUERCUS', 'EUGENIA')", }; run('trees', options, 8, t); }); @@ -122,7 +122,7 @@ test('With an >= parameter', (t) => { test('With an IN parameter and a numeric test', (t) => { const options = { - where: 'Genus IN (\'QUERCUS\', \'JACARANDA\') AND Trunk_Diameter>=13', + where: "Genus IN ('QUERCUS', 'JACARANDA') AND Trunk_Diameter>=13", }; run('trees', options, 6, t); }); @@ -130,14 +130,14 @@ test('With an IN parameter and a numeric test', (t) => { test('With an AND and an OR', (t) => { const options = { where: - '(Genus like \'%Quercus%\' AND Common_Name like \'%Live Oak%\') OR Street_Type like \'%AVE%\'', + "(Genus like '%Quercus%' AND Common_Name like '%Live Oak%') OR Street_Type like '%AVE%'", }; run('trees', options, 13, t); }); test('With an equality parameter', (t) => { const options = { - where: 'Common_Name = \'LIVE OAK\'', + where: "Common_Name = 'LIVE OAK'", }; run('trees', options, 6, t); }); @@ -381,7 +381,7 @@ test('With a ST_Intersects geometry predicate', (t) => { test('With a where and a geometry option', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", geometry: { type: 'Polygon', coordinates: [ @@ -402,7 +402,7 @@ test('With a where, geometry, limit and offset option', (t) => { t.plan(5); const data = 'trees'; const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", geometry: { type: 'Polygon', coordinates: [ @@ -478,7 +478,7 @@ test('With a multi-ring geometry and an inSR', (t) => { test('with a coded value domain', (t) => { const options = { - where: 'State = \'1\'', + where: "State = '1'", esriFields: [ { name: 'State', @@ -544,7 +544,7 @@ test('with a numeric coded value domain', (t) => { test('with a coded value domain', (t) => { const options = { - where: 'ZONING_S = \'INST\'', + where: "ZONING_S = 'INST'", esriFields: require('./fixtures/esriFields.json'), }; @@ -565,14 +565,14 @@ test('with a date query', (t) => { test('with an esri-style date query', (t) => { const options = { where: - 'survey_date >= \'2017-02-05T00:00:00.000Z\' AND survey_date <= \'2017-03-06T23:59:59.000Z\'', + "survey_date >= '2017-02-05T00:00:00.000Z' AND survey_date <= '2017-03-06T23:59:59.000Z'", }; run('trees', options, 4, t); }); test('with a timestamp query', (t) => { const options = { - where: 'survey_date >= timestamp \'2017-02-05\'', + where: "survey_date >= timestamp '2017-02-05'", }; run('trees', options, 4, t); }); @@ -580,14 +580,14 @@ test('with a timestamp query', (t) => { test('with a between query', (t) => { const options = { where: - 'survey_date between timestamp \'2017-01-06T00:00:00.000Z\' AND timestamp \'2017-02-06T23:59:59.000Z\'', + "survey_date between timestamp '2017-01-06T00:00:00.000Z' AND timestamp '2017-02-06T23:59:59.000Z'", }; run('trees', options, 2, t); }); test('with escaped single quote in query', (t) => { const options = { - where: 'Street_Name = \'GRAND\'\'S STREET\'\'S\'', + where: "Street_Name = 'GRAND''S STREET''S'", }; run('trees', options, 1, t); }); @@ -596,7 +596,7 @@ test('with a OBJECTID query on data that requires dynamic OBJECTID generation', t.plan(1); const options = { toEsri: true, - limit: 1 + limit: 1, }; const fixtures = { type: 'FeatureCollection', @@ -619,7 +619,7 @@ test('with a OBJECTID query on data that requires dynamic OBJECTID generation', const objectId = queryResult.features[0].attributes.OBJECTID; const filteredResult = winnow.query(fixtures, { toEsri: true, - where: `OBJECTID = ${objectId}` + where: `OBJECTID = ${objectId}`, }); t.equal(filteredResult.features.length, 1); }); @@ -631,7 +631,7 @@ test('with null dates in data source', (t) => { // * the geojson is passed to winnow.query with the metadata.fields populated const options = { where: - 'Date1 >= timestamp \'2020-01-05 00:00:00\' AND Date1 <= timestamp \'2020-02-08 23:59:59\'', + "Date1 >= timestamp '2020-01-05 00:00:00' AND Date1 <= timestamp '2020-02-08 23:59:59'", toEsri: true, }; t.plan(4); diff --git a/packages/winnow/test/integration/limit.spec.js b/packages/winnow/test/integration/limit.spec.js index b66c1e456..870bc3481 100644 --- a/packages/winnow/test/integration/limit.spec.js +++ b/packages/winnow/test/integration/limit.spec.js @@ -3,10 +3,10 @@ const test = require('tape'); const winnow = require('../..'); const fixture = require('./fixtures/trees.json'); -test('With a limit option', t => { +test('With a limit option', (t) => { t.plan(3); const options = { - limit: 10 + limit: 10, }; const filtered = winnow.query(fixture.features, options); t.equal(filtered.length, 10); @@ -14,11 +14,11 @@ test('With a limit option', t => { t.equal(filtered[9].properties.Common_Name, 'WINDMILL PALM'); }); -test('With a limit and an offset option', t => { +test('With a limit and an offset option', (t) => { t.plan(3); const options = { limit: 10, - offset: 11 + offset: 11, }; const filtered = winnow.query(fixture.features, options); t.equal(filtered.length, 10); @@ -26,20 +26,20 @@ test('With a limit and an offset option', t => { t.equal(filtered[9].properties.Common_Name, 'HOLLY OAK'); }); -test('With an offset option, but no limit; should return all features', t => { +test('With an offset option, but no limit; should return all features', (t) => { t.plan(1); const options = { - offset: 10 + offset: 10, }; const filtered = winnow.query(fixture.features, options); t.equal(filtered.length, 24); }); -test('With a limit and an offset larger than returned features, should return no features', t => { +test('With a limit and an offset larger than returned features, should return no features', (t) => { t.plan(1); const options = { limit: 10, - offset: 100000 + offset: 100000, }; const filtered = winnow.query(fixture.features, options); t.equal(filtered.length, 0); diff --git a/packages/winnow/test/integration/order.spec.js b/packages/winnow/test/integration/order.spec.js index 45bf75eae..2a51005b9 100644 --- a/packages/winnow/test/integration/order.spec.js +++ b/packages/winnow/test/integration/order.spec.js @@ -4,49 +4,49 @@ const _ = require('lodash'); const winnow = require('../..'); const fixture = require('./fixtures/trees.json'); -test('With a limit of 10, order by OBJECTID ASC', t => { +test('With a limit of 10, order by OBJECTID ASC', (t) => { t.plan(2); const options = { limit: 10, - order: 'OBJECTID ASC' + order: 'OBJECTID ASC', }; const filtered = winnow.query(fixture.features, options); t.equals(filtered[0].properties.OBJECTID, 316); t.equals(filtered[1].properties.OBJECTID, 317); }); -test('With a limit of 10, toEsri, and an idField, order by OBJECTID ASC', t => { +test('With a limit of 10, toEsri, and an idField, order by OBJECTID ASC', (t) => { t.plan(2); const options = { limit: 10, order: 'OBJECTID', toEsri: true, - collection: { metadata: { idField: 'OBJECTID' } } + collection: { metadata: { idField: 'OBJECTID' } }, }; const filtered = winnow.query(fixture.features, options); t.equals(filtered.features[0].attributes.OBJECTID, 316); t.equals(filtered.features[1].attributes.OBJECTID, 317); }); -test('With a limit of 10, toEsri, and an idField, order by OBJECTID DESC', t => { +test('With a limit of 10, toEsri, and an idField, order by OBJECTID DESC', (t) => { t.plan(2); const options = { limit: 10, order: 'OBJECTID DESC', toEsri: true, - collection: { metadata: { idField: 'OBJECTID' } } + collection: { metadata: { idField: 'OBJECTID' } }, }; const filtered = winnow.query(fixture.features, options); t.equals(filtered.features[0].attributes.OBJECTID, 11310); t.equals(filtered.features[1].attributes.OBJECTID, 11309); }); -test('With a limit of 10, toEsri and no idField specified (winnow generates OBJECTID), order by OBJECTID DESC', t => { +test('With a limit of 10, toEsri and no idField specified (winnow generates OBJECTID), order by OBJECTID DESC', (t) => { t.plan(3); const options = { limit: 10, order: 'OBJECTID DESC', - toEsri: true + toEsri: true, }; // Clone fixture so it isn't mutated const filtered = winnow.query(_.cloneDeep(fixture).features, options); @@ -55,12 +55,12 @@ test('With a limit of 10, toEsri and no idField specified (winnow generates OBJE t.ok(filtered[2].attributes.OBJECTID > filtered[3].attributes.OBJECTID); }); -test('With a limit of 10 and toEsri and no idField specified, order by Species DESC', t => { +test('With a limit of 10 and toEsri and no idField specified, order by Species DESC', (t) => { t.plan(2); const options = { limit: 10, order: 'Species DESC', - toEsri: true + toEsri: true, }; const features = require('./fixtures/trees.json').features; const filtered = winnow.query(features, options); diff --git a/packages/winnow/test/integration/prepare.spec.js b/packages/winnow/test/integration/prepare.spec.js index 93455e2d6..695859cfe 100644 --- a/packages/winnow/test/integration/prepare.spec.js +++ b/packages/winnow/test/integration/prepare.spec.js @@ -18,19 +18,22 @@ PARAMETER["Latitude_Of_Origin",33.5], UNIT["Foot_US",0.30480060960121924], AUTHORITY["EPSG","102645"]]`; -test('compiling a complex query', t => { +test('compiling a complex query', (t) => { try { - t.ok(Winnow.prepareQuery({ - geometry: { - xmin: -37237674.195623085, - ymin: 676003.5082798181, - xmax: 37237674.195623085, - ymax: 12416731.052879848, - spatialReference: { - wkt: 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]' - } - } - }), 'query compiled'); + t.ok( + Winnow.prepareQuery({ + geometry: { + xmin: -37237674.195623085, + ymin: 676003.5082798181, + xmax: 37237674.195623085, + ymax: 12416731.052879848, + spatialReference: { + wkt: 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-6.828007551173374],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]', + }, + }, + }), + 'query compiled', + ); t.end(); } catch (e) { t.fail(e); @@ -38,9 +41,14 @@ test('compiling a complex query', t => { } }); -test('compiling with several and statements', t => { +test('compiling with several and statements', (t) => { try { - t.ok(Winnow.prepareQuery({ where: 'ELEVATION >= 1165 AND ELEVATION <= 4365 AND POP1990 >= 8247 AND POP1990 <= 5700236' })); + t.ok( + Winnow.prepareQuery({ + where: + 'ELEVATION >= 1165 AND ELEVATION <= 4365 AND POP1990 >= 8247 AND POP1990 <= 5700236', + }), + ); t.end(); } catch (e) { t.fail(e); @@ -51,7 +59,7 @@ test('compiling with several and statements', t => { test('prepare query with where, then execute filter', (t) => { t.plan(1); const options = { - where: 'Common_Name=\'SOUTHERN MAGNOLIA\'' + where: "Common_Name='SOUTHERN MAGNOLIA'", }; const query = Winnow.prepareQuery(options); const filtered = query(trees); @@ -67,9 +75,9 @@ test('prepare query with geometry filter, then execute filter', (t) => { xmax: -118.1348, ymax: 34.1685, spatialReference: { - wkid: 4326 - } - } + wkid: 4326, + }, + }, }; const query = Winnow.prepareQuery(options); const filtered = query(trees); @@ -85,10 +93,10 @@ test('prepare query with geometry filter and projection, then execute filter', ( xmax: -118.1348, ymax: 34.1685, spatialReference: { - wkid: 4326 - } + wkid: 4326, + }, }, - projection: 3857 + projection: 3857, }; const query = Winnow.prepareQuery(options); const filtered = query(trees); @@ -106,10 +114,10 @@ test('prepare query with geometry filter and sourceSR, then execute filter on no xmax: -118.15718114376067, ymax: 34.18019950919287, spatialReference: { - wkid: 4326 - } + wkid: 4326, + }, }, - sourceSR: caStatePlaneWKT + sourceSR: caStatePlaneWKT, }; const query = Winnow.prepareQuery(options); const filtered = query(trees102645); diff --git a/packages/winnow/test/integration/project.spec.js b/packages/winnow/test/integration/project.spec.js index 95f80ef71..cb8ecd346 100644 --- a/packages/winnow/test/integration/project.spec.js +++ b/packages/winnow/test/integration/project.spec.js @@ -6,35 +6,38 @@ const geojson102645 = require('./fixtures/trees-sr-102645.json'); const polygonFeatures = require('./fixtures/polygon.json').features; const multiPolyFeatures = require('./fixtures/multipolygon.json').features; -test('Project to Web Mercator using 3857', t => { +test('Project to Web Mercator using 3857', (t) => { t.plan(2); const options = { projection: 3857, - limit: 1 + limit: 1, }; const results = winnow.query(features, options); - t.deepEqual(results[0].geometry.coordinates, [-11682713.391976157, 4857924.005275469]); + t.deepEqual( + results[0].geometry.coordinates, + [-11682713.391976157, 4857924.005275469], + ); t.equal(results[0].geometry.spatialReference, undefined); }); -test('Project to Web Mercator using 3857 and reduce the precision', t => { +test('Project to Web Mercator using 3857 and reduce the precision', (t) => { t.plan(2); const options = { projection: 3857, limit: 1, - geometryPrecision: 3 + geometryPrecision: 3, }; const results = winnow.query(features, options); t.deepEqual(results[0].geometry.coordinates, [-11682713.392, 4857924.005]); t.equal(results[0].geometry.spatialReference, undefined); }); -test('Project to Web Mercator using 3857 and translating to esri', t => { +test('Project to Web Mercator using 3857 and translating to esri', (t) => { t.plan(3); const options = { projection: 3857, limit: 1, - toEsri: true + toEsri: true, }; const results = winnow.query(features, options); t.equal(results.length, 1); @@ -42,12 +45,12 @@ test('Project to Web Mercator using 3857 and translating to esri', t => { t.equal(results[0].geometry.y, 4857924.005275469); }); -test('Project a polygon to Web Mercator using 3857 and translating to esri', t => { +test('Project a polygon to Web Mercator using 3857 and translating to esri', (t) => { t.plan(2); const options = { projection: 3857, limit: 1, - toEsri: true + toEsri: true, }; const results = winnow.query(polygonFeatures, options); @@ -59,17 +62,17 @@ test('Project a polygon to Web Mercator using 3857 and translating to esri', t = [-9216471.12251341, 4813698.293287256], [-10214432.963804673, 3874440.0897190133], [-12934368.178304385, 3424378.867175897], - [-13247454.246160466, 6496535.908013698] - ] + [-13247454.246160466, 6496535.908013698], + ], ]); }); -test('Project a multi-polygon to Web Mercator using 3857 and translating to esri', t => { +test('Project a multi-polygon to Web Mercator using 3857 and translating to esri', (t) => { t.plan(3); const options = { projection: 3857, limit: 1, - toEsri: true + toEsri: true, }; const results = winnow.query(multiPolyFeatures, options); @@ -80,35 +83,38 @@ test('Project a multi-polygon to Web Mercator using 3857 and translating to esri [-9216471.12251341, 4813698.293287256], [-10214432.963804673, 3874440.0897190133], [-12934368.178304385, 3424378.867175897], - [-13247454.246160466, 6496535.908013698] + [-13247454.246160466, 6496535.908013698], ]; t.deepEqual(results[0].geometry.rings[0][0], expected[0]); t.deepEqual(results[0].geometry.rings[1][0], expected[0]); }); -test('Project to Web Mercator using 3857 with an esri style outSR', t => { +test('Project to Web Mercator using 3857 with an esri style outSR', (t) => { t.plan(1); const options = { outSR: { latestWkid: 3857 }, - limit: 1 + limit: 1, }; const results = winnow.query(features, options); - t.deepEqual(results[0].geometry.coordinates, [-11682713.391976157, 4857924.005275469]); + t.deepEqual( + results[0].geometry.coordinates, + [-11682713.391976157, 4857924.005275469], + ); }); -test('Project to Web Mercator using 102100 when outSR is just a number', t => { +test('Project to Web Mercator using 102100 when outSR is just a number', (t) => { t.plan(2); const options = { outSR: 102100, limit: 1, - toEsri: true + toEsri: true, }; const results = winnow.query(features, options); t.equal(results[0].geometry.x, -11682713.391976157); t.equal(results[0].geometry.y, 4857924.005275469); }); -test('Project to Web Mercator using 3857 with a geo filter', t => { +test('Project to Web Mercator using 3857 with a geo filter', (t) => { t.plan(1); const options = { projection: 3857, @@ -119,40 +125,49 @@ test('Project to Web Mercator using 3857 with a geo filter', t => { xmax: 20026376.39, ymax: 20048966.1, spatialReference: { - wkid: 102100 - } - } + wkid: 102100, + }, + }, }; const results = winnow.query(features, options); - t.deepEqual(results[0].geometry.coordinates, [-11682713.391976157, 4857924.005275469]); + t.deepEqual( + results[0].geometry.coordinates, + [-11682713.391976157, 4857924.005275469], + ); }); -test('Project to Web Mercator using 102100', t => { +test('Project to Web Mercator using 102100', (t) => { t.plan(1); const options = { projection: 102100, - limit: 1 + limit: 1, }; const results = winnow.query(features, options); - t.deepEqual(results[0].geometry.coordinates, [-11682713.391976157, 4857924.005275469]); + t.deepEqual( + results[0].geometry.coordinates, + [-11682713.391976157, 4857924.005275469], + ); }); -test('Project to Web Mercator using WKT', t => { +test('Project to Web Mercator using WKT', (t) => { t.plan(1); const options = { projection: 'PROJCS["WGS_1984_Web_Mercator_Auxiliary_Sphere",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.017453292519943295]],PROJECTION["Mercator_Auxiliary_Sphere"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",0.0],PARAMETER["Standard_Parallel_1",0.0],PARAMETER["Auxiliary_Sphere_Type",0.0],UNIT["Meter",1.0]]', - limit: 1 + limit: 1, }; const results = winnow.query(features, options); - t.deepEqual(results[0].geometry.coordinates, [-11682713.391976157, 4857924.005275469]); + t.deepEqual( + results[0].geometry.coordinates, + [-11682713.391976157, 4857924.005275469], + ); }); -test('Do not project NaN coordinate values', t => { +test('Do not project NaN coordinate values', (t) => { t.plan(2); const options = { - projection: 3857 + projection: 3857, }; const modifiedFeatures = _.cloneDeep(features); modifiedFeatures[0].geometry.coordinates[0] = null; @@ -162,21 +177,21 @@ test('Do not project NaN coordinate values', t => { t.deepEqual(results[0].geometry.coordinates, [null, null]); }); -test('Project to NAD83 4269 an esri style outSR', t => { +test('Project to NAD83 4269 an esri style outSR', (t) => { t.plan(1); const options = { outSR: { latestWkid: 4269 }, - limit: 1 + limit: 1, }; const results = winnow.query(features, options); t.deepEqual(results[0].geometry.coordinates, [-104.9476, 39.9448]); }); -test('Project a polygon to NAD83 using 4269', t => { +test('Project a polygon to NAD83 using 4269', (t) => { t.plan(2); const options = { projection: 4269, - limit: 1 + limit: 1, }; const results = winnow.query(polygonFeatures, options); @@ -188,17 +203,17 @@ test('Project a polygon to NAD83 using 4269', t => { [-91.7578125, 32.84267363195431], [-82.79296874999999, 39.639537564366684], [-102.48046875, 53.014783245859206], - [-119.00390625, 50.28933925329178] - ] + [-119.00390625, 50.28933925329178], + ], ]); }); -test('Project a polygon to NAD83 using 4269 and translating to esri', t => { +test('Project a polygon to NAD83 using 4269 and translating to esri', (t) => { t.plan(2); const options = { projection: 4269, limit: 1, - toEsri: true + toEsri: true, }; const results = winnow.query(polygonFeatures, options); t.equal(results.length, 1); @@ -209,12 +224,12 @@ test('Project a polygon to NAD83 using 4269 and translating to esri', t => { [-82.79296874999999, 39.639537564366684], [-91.7578125, 32.84267363195431], [-116.19140625, 29.38217507514529], - [-119.00390625, 50.28933925329178] - ] + [-119.00390625, 50.28933925329178], + ], ]); }); -test('Project data with CRS 102645 to 3857 using wkt', t => { +test('Project data with CRS 102645 to 3857 using wkt', (t) => { t.plan(2); const options = { projection: 3857, @@ -233,54 +248,66 @@ PARAMETER["Standard_Parallel_2",35.46666666666667], PARAMETER["Latitude_Of_Origin",33.5], UNIT["Foot_US",0.30480060960121924], AUTHORITY["EPSG","102645"]]`, - limit: 1 + limit: 1, }; - const { crs, features: [feature] } = winnow.query(geojson102645, options); + const { + crs, + features: [feature], + } = winnow.query(geojson102645, options); t.deepEqual(feature.geometry, { type: 'Point', - coordinates: [ - -13153229.775672015, - 4053009.002177773 - ] + coordinates: [-13153229.775672015, 4053009.002177773], + }); + t.deepEquals(crs, { + type: 'name', + properties: { name: 'urn:ogc:def:crs:EPSG::3857' }, }); - t.deepEquals(crs, { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG::3857' } }); }); -test('Project data with CRS 102645 to 3857 using wkid', t => { +test('Project data with CRS 102645 to 3857 using wkid', (t) => { t.plan(2); const options = { projection: 3857, inputCrs: 102645, - limit: 1 + limit: 1, }; - const { crs, features: [feature] } = winnow.query(geojson102645, options); + const { + crs, + features: [feature], + } = winnow.query(geojson102645, options); t.deepEqual(feature.geometry, { type: 'Point', - coordinates: [ - -13153229.775672015, - 4053009.002177773 - ] + coordinates: [-13153229.775672015, 4053009.002177773], + }); + t.deepEquals(crs, { + type: 'name', + properties: { name: 'urn:ogc:def:crs:EPSG::3857' }, }); - t.deepEquals(crs, { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG::3857' } }); }); -test('Project data with CRS 102645 to 2285 using wkid', t => { +test('Project data with CRS 102645 to 2285 using wkid', (t) => { t.plan(2); const options = { projection: 2285, inputCrs: 102645, - limit: 1 + limit: 1, }; - const { crs, features: [feature] } = winnow.query(geojson102645, options); + const { + crs, + features: [feature], + } = winnow.query(geojson102645, options); t.deepEqual(feature.geometry, { type: 'Point', - coordinates: [2472082.3119989717, -4703451.5519728195] + coordinates: [2472082.3119989717, -4703451.5519728195], + }); + t.deepEquals(crs, { + type: 'name', + properties: { name: 'urn:ogc:def:crs:EPSG::2285' }, }); - t.deepEquals(crs, { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG::2285' } }); }); -test('Project data with CRS 102645 to 3857, use geometry filter with WGS84', t => { +test('Project data with CRS 102645 to 3857, use geometry filter with WGS84', (t) => { t.plan(3); const options = { projection: 3857, @@ -291,23 +318,23 @@ test('Project data with CRS 102645 to 3857, use geometry filter with WGS84', t = xmax: -118.15745575823779, ymax: 34.18010065453462, spatialReference: { - wkid: 4326 - } - } + wkid: 4326, + }, + }, }; const { crs, features } = winnow.query(geojson102645, options); t.equals(features.length, 1); t.deepEqual(features[0].geometry, { type: 'Point', - coordinates: [ - -13153229.775672015, - 4053009.002177773 - ] + coordinates: [-13153229.775672015, 4053009.002177773], + }); + t.deepEquals(crs, { + type: 'name', + properties: { name: 'urn:ogc:def:crs:EPSG::3857' }, }); - t.deepEquals(crs, { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG::3857' } }); }); -test('Project data with CRS 102645 to 3857, use geometry filter with 102645', t => { +test('Project data with CRS 102645 to 3857, use geometry filter with 102645', (t) => { t.plan(3); const options = { projection: 3857, @@ -318,18 +345,18 @@ test('Project data with CRS 102645 to 3857, use geometry filter with 102645', t xmax: 6514044.291980494, ymax: 1887961.5157372837, spatialReference: { - wkid: 102645 - } - } + wkid: 102645, + }, + }, }; const { crs, features } = winnow.query(geojson102645, options); t.equals(features.length, 1); t.deepEqual(features[0].geometry, { type: 'Point', - coordinates: [ - -13153229.775672015, - 4053009.002177773 - ] + coordinates: [-13153229.775672015, 4053009.002177773], + }); + t.deepEquals(crs, { + type: 'name', + properties: { name: 'urn:ogc:def:crs:EPSG::3857' }, }); - t.deepEquals(crs, { type: 'name', properties: { name: 'urn:ogc:def:crs:EPSG::3857' } }); }); diff --git a/packages/winnow/test/integration/to-esri.spec.js b/packages/winnow/test/integration/to-esri.spec.js index 94fee05f8..6f50d141d 100644 --- a/packages/winnow/test/integration/to-esri.spec.js +++ b/packages/winnow/test/integration/to-esri.spec.js @@ -7,7 +7,7 @@ const emptyCollection = require('./fixtures/emptyCollection.json'); const Winnow = require('../..'); const _ = require('lodash'); -test('detecting fields', t => { +test('detecting fields', (t) => { const options = {}; const result = Winnow.query(geojson, options); const metadata = result.metadata; @@ -18,11 +18,11 @@ test('detecting fields', t => { t.end(); }); -test('With a where option and a limit smaller than the filter', t => { +test('With a where option and a limit smaller than the filter', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", limit: 1, - toEsri: true + toEsri: true, }; const result = Winnow.query(trees, options); const metadata = result.metadata; @@ -30,10 +30,10 @@ test('With a where option and a limit smaller than the filter', t => { t.end(); }); -test('With a where option and a limit larger than the filter', t => { +test('With a where option and a limit larger than the filter', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', - toEsri: true + where: "Genus like '%Quercus%'", + toEsri: true, }; const result = Winnow.query(trees, options); const metadata = result.metadata; @@ -41,11 +41,11 @@ test('With a where option and a limit larger than the filter', t => { t.end(); }); -test('With a where option and a limit the same as the the filter', t => { +test('With a where option and a limit the same as the the filter', (t) => { const options = { - where: 'Genus like \'%Quercus%\'', + where: "Genus like '%Quercus%'", toEsri: true, - limit: 12105 + limit: 12105, }; const result = Winnow.query(trees, options); const metadata = result.metadata; @@ -53,9 +53,9 @@ test('With a where option and a limit the same as the the filter', t => { t.end(); }); -test('handling errors when feature collection is empty', t => { +test('handling errors when feature collection is empty', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(emptyCollection); const result = Winnow.query(fixture, options); @@ -64,9 +64,9 @@ test('handling errors when feature collection is empty', t => { t.end(); }); -test('checking if an object id exists', t => { +test('checking if an object id exists', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(oidFeature); const result = Winnow.query(fixture, options); @@ -75,14 +75,14 @@ test('checking if an object id exists', t => { t.end(); }); -test('use idField not name OBJECTID', t => { +test('use idField not name OBJECTID', (t) => { const options = { toEsri: true, - fields: 'featureId' + fields: 'featureId', }; const fixture = _.cloneDeep(treesFeatureId); fixture.metadata = { - idField: 'featureId' + idField: 'featureId', }; const result = Winnow.query(fixture, options); t.ok(_.has(result, 'features[0].attributes.featureId')); @@ -91,9 +91,9 @@ test('use idField not name OBJECTID', t => { t.end(); }); -test('adding an object id', t => { +test('adding an object id', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(geojson); @@ -105,23 +105,22 @@ test('adding an object id', t => { try { // If requiring farmhash is successful we use that hash hasher = require('farmhash').hash32; - + // eslint-disable-next-line } catch (e) { // Else use the string-hash number hasher = require('string-hash'); - } - const hash = hasher(JSON.stringify({ properties, geometry})); - const objectId = Math.round((hash / 4294967295) * (2147483647)); + const hash = hasher(JSON.stringify({ properties, geometry })); + const objectId = Math.round((hash / 4294967295) * 2147483647); const result = Winnow.query(fixture, options); t.equal(result.features[0].attributes.OBJECTID, objectId); t.end(); }); -test('do not overwrite the object id', t => { +test('do not overwrite the object id', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(geojson); @@ -133,9 +132,9 @@ test('do not overwrite the object id', t => { t.end(); }); -test('do not include Type', t => { +test('do not include Type', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(geojson); @@ -147,9 +146,9 @@ test('do not include Type', t => { t.end(); }); -test('converting date fields', t => { +test('converting date fields', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = _.cloneDeep(geojson); const result = Winnow.query(fixture, options); @@ -158,31 +157,31 @@ test('converting date fields', t => { t.end(); }); -test('converting date with passed in fields metadata', t => { +test('converting date with passed in fields metadata', (t) => { const options = { - toEsri: true + toEsri: true, }; const fixture = Object.assign({}, _.cloneDeep(geojson), { metdata: { fields: [ { name: 'double', - type: 'Double' + type: 'Double', }, { name: 'integer', - type: 'Integer' + type: 'Integer', }, { name: 'string', - type: 'String' + type: 'String', }, { name: 'date', - type: 'Date' - } - ] - } + type: 'Date', + }, + ], + }, }); const result = Winnow.query(fixture, options); t.equal(result.features[0].attributes.date, 1331769600000); @@ -190,10 +189,10 @@ test('converting date with passed in fields metadata', t => { t.end(); }); -test('exclude objectid addition when not part of outfields', t => { +test('exclude objectid addition when not part of outfields', (t) => { const options = { toEsri: true, - outFields: ['string'] + outFields: ['string'], }; const fixture = _.cloneDeep(geojson); const result = Winnow.query(fixture, options); @@ -202,11 +201,11 @@ test('exclude objectid addition when not part of outfields', t => { t.end(); }); -test('do not exclude objectid when returnIdsOnly = true', t => { +test('do not exclude objectid when returnIdsOnly = true', (t) => { const options = { toEsri: true, outFields: ['string'], - returnIdsOnly: true + returnIdsOnly: true, }; const fixture = _.cloneDeep(geojson); const result = Winnow.query(fixture, options); diff --git a/packages/winnow/test/integration/wfs.spec.js b/packages/winnow/test/integration/wfs.spec.js index 7e1f0f5fe..6568b11c6 100644 --- a/packages/winnow/test/integration/wfs.spec.js +++ b/packages/winnow/test/integration/wfs.spec.js @@ -1,11 +1,11 @@ const test = require('tape'); const winnow = require('../..'); -test('WFS with a bbox in Web Mercator with geojson output', t => { +test('WFS with a bbox in Web Mercator with geojson output', (t) => { const options = { outputFormat: 'application/json', bbox: '-118.163,34.162,-118.108,34.173,EPSG:4326', - srsName: 'EPSG:4326' + srsName: 'EPSG:4326', }; t.plan(1); const features = require('./fixtures/trees.json').features; diff --git a/test/geoservice-client-requests-provider-w-id-field.spec.js b/test/geoservice-client-requests-provider-w-id-field.spec.js index 633f804b1..470b2a90a 100644 --- a/test/geoservice-client-requests-provider-w-id-field.spec.js +++ b/test/geoservice-client-requests-provider-w-id-field.spec.js @@ -105,7 +105,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&objectIds=${objectIds[0]}&outFields=*&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); test('filter by objectIds, return all outFields defined by layer info', async () => { @@ -123,7 +125,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie )}&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); }); @@ -159,7 +163,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&&resultOffset=0&resultRecordCount=50&where=1%3D1&orderByFields=&outFields=*&returnGeometry=false&spatialRel=esriSpatialRelIntersects`, ); - expect(featuresResponse.body).toEqual(getAttributeTable(IDFIELD, objectIds)); + expect(featuresResponse.body).toEqual( + getAttributeTable(IDFIELD, objectIds), + ); }); }); }); diff --git a/test/geoservice-client-requests-provider-w-objectids.spec.js b/test/geoservice-client-requests-provider-w-objectids.spec.js index c6bb63864..3502b9cd6 100644 --- a/test/geoservice-client-requests-provider-w-objectids.spec.js +++ b/test/geoservice-client-requests-provider-w-objectids.spec.js @@ -105,7 +105,9 @@ describe('Typical Geoservice Client request sequence: Dataset with OBJECTID as a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&objectIds=${objectIds[0]}&outFields=*&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); test('filter by objectIds, return all outFields defined by layer info', async () => { @@ -123,7 +125,9 @@ describe('Typical Geoservice Client request sequence: Dataset with OBJECTID as a )}&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); }); @@ -159,7 +163,9 @@ describe('Typical Geoservice Client request sequence: Dataset with OBJECTID as a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&&resultOffset=0&resultRecordCount=50&where=1%3D1&orderByFields=&outFields=*&returnGeometry=false&spatialRel=esriSpatialRelIntersects`, ); - expect(featuresResponse.body).toEqual(getAttributeTable(IDFIELD, objectIds)); + expect(featuresResponse.body).toEqual( + getAttributeTable(IDFIELD, objectIds), + ); }); }); }); diff --git a/test/geoservice-client-requests-provider-w-string-id-field.spec.js b/test/geoservice-client-requests-provider-w-string-id-field.spec.js index 14446dd40..bc0d9ecc3 100644 --- a/test/geoservice-client-requests-provider-w-string-id-field.spec.js +++ b/test/geoservice-client-requests-provider-w-string-id-field.spec.js @@ -105,7 +105,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&objectIds=${objectIds[0]}&outFields=*&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); test('filter by objectIds, return all outFields defined by layer info', async () => { @@ -123,7 +125,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie )}&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); }); @@ -159,7 +163,9 @@ describe('Typical Geoservice Client request sequence: Dataset with defined idFie `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&&resultOffset=0&resultRecordCount=50&where=1%3D1&orderByFields=&outFields=*&returnGeometry=false&spatialRel=esriSpatialRelIntersects`, ); - expect(featuresResponse.body).toEqual(getAttributeTable(IDFIELD, objectIds)); + expect(featuresResponse.body).toEqual( + getAttributeTable(IDFIELD, objectIds), + ); }); }); }); diff --git a/test/geoservice-client-requests-provider-wo-objectids-wo-fields-def.spec.js b/test/geoservice-client-requests-provider-wo-objectids-wo-fields-def.spec.js index 5971ec07c..28ff9f765 100644 --- a/test/geoservice-client-requests-provider-wo-objectids-wo-fields-def.spec.js +++ b/test/geoservice-client-requests-provider-wo-objectids-wo-fields-def.spec.js @@ -105,7 +105,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&objectIds=${objectIds[0]}&outFields=*&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); test('filter by objectIds, return all outFields defined by layer info', async () => { @@ -123,7 +125,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a )}&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); }); @@ -159,7 +163,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&&resultOffset=0&resultRecordCount=50&where=1%3D1&orderByFields=&outFields=*&returnGeometry=false&spatialRel=esriSpatialRelIntersects`, ); - expect(featuresResponse.body).toEqual(getAttributeTable(IDFIELD, objectIds)); + expect(featuresResponse.body).toEqual( + getAttributeTable(IDFIELD, objectIds), + ); }); }); }); diff --git a/test/geoservice-client-requests-provider-wo-objectids.spec.js b/test/geoservice-client-requests-provider-wo-objectids.spec.js index 8038d932a..4930a5226 100644 --- a/test/geoservice-client-requests-provider-wo-objectids.spec.js +++ b/test/geoservice-client-requests-provider-wo-objectids.spec.js @@ -105,7 +105,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&objectIds=${objectIds[0]}&outFields=*&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); test('filter by objectIds, return all outFields defined by layer info', async () => { @@ -123,7 +125,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a )}&outSR=102100&spatialRel=esriSpatialRelIntersects&where=1%3D1`, ); - expect(identifyResponse.body).toEqual(filterByObjectIds(IDFIELD, objectIds)); + expect(identifyResponse.body).toEqual( + filterByObjectIds(IDFIELD, objectIds), + ); }); }); @@ -159,7 +163,9 @@ describe('Typical Geoservice Client request sequence: Dataset without OBJECTID a `/file-geojson/rest/services/${idUrlParam}/FeatureServer/0/query?f=json&&resultOffset=0&resultRecordCount=50&where=1%3D1&orderByFields=&outFields=*&returnGeometry=false&spatialRel=esriSpatialRelIntersects`, ); - expect(featuresResponse.body).toEqual(getAttributeTable(IDFIELD, objectIds)); + expect(featuresResponse.body).toEqual( + getAttributeTable(IDFIELD, objectIds), + ); }); }); }); diff --git a/test/geoservice-error-handling.spec.js b/test/geoservice-error-handling.spec.js index 612083036..267e9bc38 100644 --- a/test/geoservice-error-handling.spec.js +++ b/test/geoservice-error-handling.spec.js @@ -58,7 +58,7 @@ describe('geoservices error handling', () => { code: 499, details: ['Token Required'], message: 'Token Required', - messageCode: 'GWM_0003' + messageCode: 'GWM_0003', }, }); } catch (error) { @@ -108,7 +108,9 @@ describe('geoservices error handling', () => { dataDir: './test/provider-data', }); try { - const response = await request(koop.server).get('/file-geojson/rest/generateToken'); + const response = await request(koop.server).get( + '/file-geojson/rest/generateToken', + ); expect(response.status).toBe(200); expect(response.body).toEqual({ error: { diff --git a/test/geoservice-pbf.spec.js b/test/geoservice-pbf.spec.js index b2cce1a64..49070c1fe 100644 --- a/test/geoservice-pbf.spec.js +++ b/test/geoservice-pbf.spec.js @@ -74,7 +74,7 @@ describe('koop', () => { { low: 769803776, high: -6, unsigned: false }, ], }, - } + }, ], }, }, diff --git a/test/helpers/output-pull-with-callback.js b/test/helpers/output-pull-with-callback.js index 4ce5862d1..ee79ebe7b 100644 --- a/test/helpers/output-pull-with-callback.js +++ b/test/helpers/output-pull-with-callback.js @@ -2,15 +2,17 @@ class Output { static type = 'output'; static version = '0.0.1'; static name = 'output-using-pull-callback'; - static routes = [ { - path: '$namespace/output-path', - methods: ['get', 'post'], - handler: 'handler', - },]; + static routes = [ + { + path: '$namespace/output-path', + methods: ['get', 'post'], + handler: 'handler', + }, + ]; - handler (req, res, next) { + handler(req, res, next) { this.model.pull(req, (err, data) => { - if(err) { + if (err) { return next(err); } res.status(200).json(data); diff --git a/test/helpers/provider-async-no-callback.js b/test/helpers/provider-async-no-callback.js index 807976edb..304793a26 100644 --- a/test/helpers/provider-async-no-callback.js +++ b/test/helpers/provider-async-no-callback.js @@ -6,7 +6,7 @@ class Model { { type: 'Feature', properties: { - OBJECTID: 1 + OBJECTID: 1, }, geometry: { type: 'Point', diff --git a/test/helpers/provider-async-with-callback.js b/test/helpers/provider-async-with-callback.js index ebbe43591..b306996ea 100644 --- a/test/helpers/provider-async-with-callback.js +++ b/test/helpers/provider-async-with-callback.js @@ -6,7 +6,7 @@ class Model { { type: 'Feature', properties: { - OBJECTID: 1 + OBJECTID: 1, }, geometry: { type: 'Point', diff --git a/test/helpers/provider-callback.js b/test/helpers/provider-callback.js index 2d7a634aa..8f54dd1cb 100644 --- a/test/helpers/provider-callback.js +++ b/test/helpers/provider-callback.js @@ -6,7 +6,7 @@ class Model { { type: 'Feature', properties: { - OBJECTID: 1 + OBJECTID: 1, }, geometry: { type: 'Point',