@mapcreator/api 3.3.0 → 5.0.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +82 -59
- package/cjs/api/apiCommon.d.ts +7 -0
- package/cjs/api/apiCommon.d.ts.map +1 -0
- package/cjs/api/apiCommon.js +32 -0
- package/cjs/api/apiCommon.js.map +1 -0
- package/cjs/api/choropleth.d.ts +206 -0
- package/cjs/api/choropleth.d.ts.map +1 -0
- package/cjs/api/choropleth.js +40 -0
- package/cjs/api/choropleth.js.map +1 -0
- package/cjs/api/color.d.ts +16 -0
- package/cjs/api/color.d.ts.map +1 -0
- package/cjs/api/color.js +8 -0
- package/cjs/api/color.js.map +1 -0
- package/cjs/api/dimension.d.ts +25 -0
- package/cjs/api/dimension.d.ts.map +1 -0
- package/cjs/api/dimension.js +19 -0
- package/cjs/api/dimension.js.map +1 -0
- package/cjs/api/dimensionSet.d.ts +15 -0
- package/cjs/api/dimensionSet.d.ts.map +1 -0
- package/cjs/api/dimensionSet.js +7 -0
- package/cjs/api/dimensionSet.js.map +1 -0
- package/cjs/api/feature.d.ts +16 -0
- package/cjs/api/feature.d.ts.map +1 -0
- package/cjs/api/feature.js +8 -0
- package/cjs/api/feature.js.map +1 -0
- package/cjs/api/font.d.ts +22 -0
- package/cjs/api/font.d.ts.map +1 -0
- package/cjs/api/font.js +10 -0
- package/cjs/api/font.js.map +1 -0
- package/cjs/api/fontFamily.d.ts +17 -0
- package/cjs/api/fontFamily.d.ts.map +1 -0
- package/cjs/api/fontFamily.js +17 -0
- package/cjs/api/fontFamily.js.map +1 -0
- package/cjs/api/highlight.d.ts +41 -0
- package/cjs/api/highlight.d.ts.map +1 -0
- package/cjs/api/highlight.js +17 -0
- package/cjs/api/highlight.js.map +1 -0
- package/cjs/api/job.d.ts +40 -0
- package/cjs/api/job.d.ts.map +1 -0
- package/cjs/api/job.js +70 -0
- package/cjs/api/job.js.map +1 -0
- package/cjs/api/jobResult.d.ts +29 -0
- package/cjs/api/jobResult.d.ts.map +1 -0
- package/cjs/api/jobResult.js +35 -0
- package/cjs/api/jobResult.js.map +1 -0
- package/cjs/api/jobRevision.d.ts +43 -0
- package/cjs/api/jobRevision.d.ts.map +1 -0
- package/cjs/api/jobRevision.js +72 -0
- package/cjs/api/jobRevision.js.map +1 -0
- package/cjs/api/jobShare.d.ts +26 -0
- package/cjs/api/jobShare.d.ts.map +1 -0
- package/cjs/api/jobShare.js +10 -0
- package/cjs/api/jobShare.js.map +1 -0
- package/cjs/api/jobType.d.ts +17 -0
- package/cjs/api/jobType.d.ts.map +1 -0
- package/cjs/api/jobType.js +11 -0
- package/cjs/api/jobType.js.map +1 -0
- package/cjs/api/language.d.ts +17 -0
- package/cjs/api/language.d.ts.map +1 -0
- package/cjs/api/language.js +3 -0
- package/cjs/api/language.js.map +1 -0
- package/cjs/api/layer.d.ts +24 -0
- package/cjs/api/layer.d.ts.map +1 -0
- package/cjs/api/layer.js +14 -0
- package/cjs/api/layer.js.map +1 -0
- package/cjs/api/layerFaq.d.ts +27 -0
- package/cjs/api/layerFaq.d.ts.map +1 -0
- package/cjs/api/layerFaq.js +16 -0
- package/cjs/api/layerFaq.js.map +1 -0
- package/cjs/api/layerGroup.d.ts +16 -0
- package/cjs/api/layerGroup.d.ts.map +1 -0
- package/cjs/api/layerGroup.js +37 -0
- package/cjs/api/layerGroup.js.map +1 -0
- package/cjs/api/mapstyleSet.d.ts +29 -0
- package/cjs/api/mapstyleSet.d.ts.map +1 -0
- package/cjs/api/mapstyleSet.js +19 -0
- package/cjs/api/mapstyleSet.js.map +1 -0
- package/cjs/api/message.d.ts +32 -0
- package/cjs/api/message.d.ts.map +1 -0
- package/cjs/api/message.js +37 -0
- package/cjs/api/message.js.map +1 -0
- package/cjs/api/organisation.d.ts +38 -0
- package/cjs/api/organisation.d.ts.map +1 -0
- package/cjs/api/organisation.js +43 -0
- package/cjs/api/organisation.js.map +1 -0
- package/cjs/api/resources.d.ts +54 -0
- package/cjs/api/resources.d.ts.map +1 -0
- package/cjs/api/resources.js +55 -0
- package/cjs/api/resources.js.map +1 -0
- package/cjs/api/svg.d.ts +21 -0
- package/cjs/api/svg.d.ts.map +1 -0
- package/cjs/api/svg.js +15 -0
- package/cjs/api/svg.js.map +1 -0
- package/cjs/api/svgSet.d.ts +22 -0
- package/cjs/api/svgSet.d.ts.map +1 -0
- package/cjs/api/svgSet.js +25 -0
- package/cjs/api/svgSet.js.map +1 -0
- package/cjs/api/user.d.ts +100 -0
- package/cjs/api/user.d.ts.map +1 -0
- package/cjs/api/user.js +126 -0
- package/cjs/api/user.js.map +1 -0
- package/cjs/index.d.ts +26 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +51 -0
- package/cjs/index.js.map +1 -0
- package/cjs/oauth.d.ts +20 -0
- package/cjs/oauth.d.ts.map +1 -0
- package/cjs/oauth.js +229 -0
- package/cjs/oauth.js.map +1 -0
- package/cjs/utils.d.ts +72 -0
- package/cjs/utils.d.ts.map +1 -0
- package/cjs/utils.js +220 -0
- package/cjs/utils.js.map +1 -0
- package/esm/api/apiCommon.d.ts +7 -0
- package/esm/api/apiCommon.d.ts.map +1 -0
- package/esm/api/apiCommon.js +28 -0
- package/esm/api/apiCommon.js.map +1 -0
- package/esm/api/choropleth.d.ts +206 -0
- package/esm/api/choropleth.d.ts.map +1 -0
- package/esm/api/choropleth.js +32 -0
- package/esm/api/choropleth.js.map +1 -0
- package/esm/api/color.d.ts +16 -0
- package/esm/api/color.d.ts.map +1 -0
- package/esm/api/color.js +5 -0
- package/esm/api/color.js.map +1 -0
- package/esm/api/dimension.d.ts +25 -0
- package/esm/api/dimension.d.ts.map +1 -0
- package/esm/api/dimension.js +16 -0
- package/esm/api/dimension.js.map +1 -0
- package/esm/api/dimensionSet.d.ts +15 -0
- package/esm/api/dimensionSet.d.ts.map +1 -0
- package/esm/api/dimensionSet.js +4 -0
- package/esm/api/dimensionSet.js.map +1 -0
- package/esm/api/feature.d.ts +16 -0
- package/esm/api/feature.d.ts.map +1 -0
- package/esm/api/feature.js +5 -0
- package/esm/api/feature.js.map +1 -0
- package/esm/api/font.d.ts +22 -0
- package/esm/api/font.d.ts.map +1 -0
- package/esm/api/font.js +7 -0
- package/esm/api/font.js.map +1 -0
- package/esm/api/fontFamily.d.ts +17 -0
- package/esm/api/fontFamily.d.ts.map +1 -0
- package/esm/api/fontFamily.js +13 -0
- package/esm/api/fontFamily.js.map +1 -0
- package/esm/api/highlight.d.ts +41 -0
- package/esm/api/highlight.d.ts.map +1 -0
- package/esm/api/highlight.js +12 -0
- package/esm/api/highlight.js.map +1 -0
- package/esm/api/job.d.ts +40 -0
- package/esm/api/job.d.ts.map +1 -0
- package/esm/api/job.js +58 -0
- package/esm/api/job.js.map +1 -0
- package/esm/api/jobResult.d.ts +29 -0
- package/esm/api/jobResult.d.ts.map +1 -0
- package/esm/api/jobResult.js +30 -0
- package/esm/api/jobResult.js.map +1 -0
- package/esm/api/jobRevision.d.ts +43 -0
- package/esm/api/jobRevision.d.ts.map +1 -0
- package/esm/api/jobRevision.js +63 -0
- package/esm/api/jobRevision.js.map +1 -0
- package/esm/api/jobShare.d.ts +26 -0
- package/esm/api/jobShare.d.ts.map +1 -0
- package/esm/api/jobShare.js +6 -0
- package/esm/api/jobShare.js.map +1 -0
- package/esm/api/jobType.d.ts +17 -0
- package/esm/api/jobType.d.ts.map +1 -0
- package/esm/api/jobType.js +8 -0
- package/esm/api/jobType.js.map +1 -0
- package/esm/api/language.d.ts +17 -0
- package/esm/api/language.d.ts.map +1 -0
- package/esm/api/language.js +2 -0
- package/esm/api/language.js.map +1 -0
- package/esm/api/layer.d.ts +24 -0
- package/esm/api/layer.d.ts.map +1 -0
- package/esm/api/layer.js +11 -0
- package/esm/api/layer.js.map +1 -0
- package/esm/api/layerFaq.d.ts +27 -0
- package/esm/api/layerFaq.d.ts.map +1 -0
- package/esm/api/layerFaq.js +12 -0
- package/esm/api/layerFaq.js.map +1 -0
- package/esm/api/layerGroup.d.ts +16 -0
- package/esm/api/layerGroup.d.ts.map +1 -0
- package/esm/api/layerGroup.js +33 -0
- package/esm/api/layerGroup.js.map +1 -0
- package/esm/api/mapstyleSet.d.ts +29 -0
- package/esm/api/mapstyleSet.d.ts.map +1 -0
- package/esm/api/mapstyleSet.js +16 -0
- package/esm/api/mapstyleSet.js.map +1 -0
- package/esm/api/message.d.ts +32 -0
- package/esm/api/message.d.ts.map +1 -0
- package/esm/api/message.js +32 -0
- package/esm/api/message.js.map +1 -0
- package/esm/api/organisation.d.ts +38 -0
- package/esm/api/organisation.d.ts.map +1 -0
- package/esm/api/organisation.js +37 -0
- package/esm/api/organisation.js.map +1 -0
- package/esm/api/resources.d.ts +54 -0
- package/esm/api/resources.d.ts.map +1 -0
- package/esm/api/resources.js +48 -0
- package/esm/api/resources.js.map +1 -0
- package/esm/api/svg.d.ts +21 -0
- package/esm/api/svg.d.ts.map +1 -0
- package/esm/api/svg.js +11 -0
- package/esm/api/svg.js.map +1 -0
- package/esm/api/svgSet.d.ts +22 -0
- package/esm/api/svgSet.d.ts.map +1 -0
- package/esm/api/svgSet.js +21 -0
- package/esm/api/svgSet.js.map +1 -0
- package/esm/api/user.d.ts +100 -0
- package/esm/api/user.d.ts.map +1 -0
- package/esm/api/user.js +110 -0
- package/esm/api/user.js.map +1 -0
- package/esm/index.d.ts +26 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +26 -0
- package/esm/index.js.map +1 -0
- package/esm/oauth.d.ts +20 -0
- package/esm/oauth.d.ts.map +1 -0
- package/esm/oauth.js +222 -0
- package/esm/oauth.js.map +1 -0
- package/esm/utils.d.ts +72 -0
- package/esm/utils.d.ts.map +1 -0
- package/esm/utils.js +206 -0
- package/esm/utils.js.map +1 -0
- package/package.json +66 -137
- package/src/README.md +126 -0
- package/src/api/apiCommon.ts +70 -0
- package/src/api/choropleth.ts +318 -0
- package/src/api/color.ts +22 -0
- package/src/api/dimension.ts +54 -0
- package/src/api/dimensionSet.ts +20 -0
- package/src/api/feature.ts +22 -0
- package/src/api/font.ts +30 -0
- package/src/api/fontFamily.ts +43 -0
- package/src/api/highlight.ts +74 -0
- package/src/api/job.ts +127 -0
- package/src/api/jobResult.ts +81 -0
- package/src/api/jobRevision.ts +170 -0
- package/src/api/jobShare.ts +35 -0
- package/src/api/jobType.ts +26 -0
- package/src/api/language.ts +19 -0
- package/src/api/layer.ts +36 -0
- package/src/api/layerFaq.ts +53 -0
- package/src/api/layerGroup.ts +69 -0
- package/src/api/mapstyleSet.ts +46 -0
- package/src/api/message.ts +80 -0
- package/src/api/organisation.ts +94 -0
- package/src/api/resources.ts +134 -0
- package/src/api/svg.ts +33 -0
- package/src/api/svgSet.ts +56 -0
- package/src/api/user.ts +280 -0
- package/src/index.ts +42 -0
- package/src/oauth.ts +292 -0
- package/src/utils.ts +342 -0
- package/dist/ImageHandler.d.ts +0 -56
- package/dist/Mapcreator.d.ts +0 -338
- package/dist/PaginatedResourceListing.d.ts +0 -156
- package/dist/RequestParameters.d.ts +0 -241
- package/dist/ResourceLister.d.ts +0 -155
- package/dist/bundle.browser.js +0 -14590
- package/dist/bundle.browser.min.js +0 -3
- package/dist/bundle.browser.min.js.LICENSE.txt +0 -74
- package/dist/bundle.js +0 -12755
- package/dist/bundle.min.js +0 -3
- package/dist/bundle.min.js.LICENSE.txt +0 -44
- package/dist/enums/DeletedState.d.ts +0 -16
- package/dist/enums/Enum.d.ts +0 -40
- package/dist/enums/JobShareVisibility.d.ts +0 -15
- package/dist/enums/ResultStatus.d.ts +0 -17
- package/dist/enums/index.d.ts +0 -5
- package/dist/errors/AbstractError.d.ts +0 -26
- package/dist/errors/ApiError.d.ts +0 -65
- package/dist/errors/GeoError.d.ts +0 -6
- package/dist/errors/NodeError.d.ts +0 -6
- package/dist/errors/OAuthError.d.ts +0 -17
- package/dist/errors/StaticClassError.d.ts +0 -7
- package/dist/errors/ValidationError.d.ts +0 -125
- package/dist/errors/index.d.ts +0 -8
- package/dist/index.d.ts +0 -27
- package/dist/oauth/DummyFlow.d.ts +0 -19
- package/dist/oauth/ImplicitFlow.d.ts +0 -68
- package/dist/oauth/ImplicitFlowPopup.d.ts +0 -25
- package/dist/oauth/OAuth.d.ts +0 -50
- package/dist/oauth/OAuthToken.d.ts +0 -67
- package/dist/oauth/PasswordFlow.d.ts +0 -56
- package/dist/oauth/StateContainer.d.ts +0 -36
- package/dist/proxy/GeoResourceProxy.d.ts +0 -69
- package/dist/proxy/OrganisationProxy.d.ts +0 -62
- package/dist/proxy/OwnedResourceProxy.d.ts +0 -60
- package/dist/proxy/ResourceProxy.d.ts +0 -32
- package/dist/proxy/SimpleResourceProxy.d.ts +0 -76
- package/dist/proxy/index.d.ts +0 -6
- package/dist/resources/Choropleth.d.ts +0 -20
- package/dist/resources/Color.d.ts +0 -9
- package/dist/resources/Contract.d.ts +0 -7
- package/dist/resources/Dimension.d.ts +0 -7
- package/dist/resources/DimensionSet.d.ts +0 -11
- package/dist/resources/Domain.d.ts +0 -7
- package/dist/resources/Faq.d.ts +0 -7
- package/dist/resources/Feature.d.ts +0 -9
- package/dist/resources/Font.d.ts +0 -4
- package/dist/resources/FontFamily.d.ts +0 -11
- package/dist/resources/Highlight.d.ts +0 -4
- package/dist/resources/InsetMap.d.ts +0 -10
- package/dist/resources/Job.d.ts +0 -56
- package/dist/resources/JobResult.d.ts +0 -76
- package/dist/resources/JobRevision.d.ts +0 -64
- package/dist/resources/JobShare.d.ts +0 -15
- package/dist/resources/JobType.d.ts +0 -9
- package/dist/resources/Language.d.ts +0 -4
- package/dist/resources/Layer.d.ts +0 -10
- package/dist/resources/LayerFaq.d.ts +0 -8
- package/dist/resources/LayerGroup.d.ts +0 -14
- package/dist/resources/Mapstyle.d.ts +0 -8
- package/dist/resources/MapstyleSet.d.ts +0 -13
- package/dist/resources/MapstyleSetColor.d.ts +0 -8
- package/dist/resources/Message.d.ts +0 -7
- package/dist/resources/MessageVariant.d.ts +0 -4
- package/dist/resources/Notification.d.ts +0 -4
- package/dist/resources/Organisation.d.ts +0 -99
- package/dist/resources/OrganisationNote.d.ts +0 -17
- package/dist/resources/Permission.d.ts +0 -4
- package/dist/resources/ProductTour.d.ts +0 -10
- package/dist/resources/ProductTourStep.d.ts +0 -7
- package/dist/resources/Role.d.ts +0 -14
- package/dist/resources/Svg.d.ts +0 -4
- package/dist/resources/SvgSet.d.ts +0 -11
- package/dist/resources/Tag.d.ts +0 -9
- package/dist/resources/TagType.d.ts +0 -13
- package/dist/resources/User.d.ts +0 -119
- package/dist/resources/VectorChoropleth.d.ts +0 -4
- package/dist/resources/VectorHighlight.d.ts +0 -4
- package/dist/resources/base/CrudBase.d.ts +0 -66
- package/dist/resources/base/CrudBase.d.ts.map +0 -1
- package/dist/resources/base/CrudSetBase.d.ts +0 -27
- package/dist/resources/base/CrudSetBase.d.ts.map +0 -1
- package/dist/resources/base/CrudSetItemBase.d.ts +0 -19
- package/dist/resources/base/CrudSetItemBase.d.ts.map +0 -1
- package/dist/resources/base/DownloadedResource.d.ts +0 -72
- package/dist/resources/base/DownloadedResource.d.ts.map +0 -1
- package/dist/resources/base/ResourceBase.d.ts +0 -164
- package/dist/resources/base/ResourceBase.d.ts.map +0 -1
- package/dist/resources/index.d.ts +0 -47
- package/dist/storage/CookiesDriver.d.ts +0 -37
- package/dist/storage/DataStoreContract.d.ts +0 -46
- package/dist/storage/DummyDriver.d.ts +0 -15
- package/dist/storage/FileDriver.d.ts +0 -54
- package/dist/storage/LocalStorageDriver.d.ts +0 -13
- package/dist/storage/StorageManager.d.ts +0 -46
- package/dist/traits/HandlesImages.d.ts +0 -15
- package/dist/traits/Injectable.d.ts +0 -60
- package/dist/traits/OwnableResource.d.ts +0 -18
- package/dist/traits/Trait.d.ts +0 -12
- package/dist/utils/Logger.d.ts +0 -55
- package/dist/utils/Singleton.d.ts +0 -9
- package/dist/utils/StaticClass.d.ts +0 -7
- package/dist/utils/Unobservable.d.ts +0 -13
- package/dist/utils/base64.d.ts +0 -12
- package/dist/utils/geo.d.ts +0 -74
- package/dist/utils/hash.d.ts +0 -15
- package/dist/utils/helpers.d.ts +0 -47
- package/dist/utils/node.d.ts +0 -15
- package/dist/utils/reflection.d.ts +0 -43
- package/dist/utils/requests.d.ts +0 -24
- package/dist/utils/uuid.d.ts +0 -19
- package/manual/assets/maps4news.svg +0 -23
- package/manual/building.md +0 -19
- package/manual/css/hide_import.css +0 -3
- package/manual/css/sidebar_fix.css +0 -3
- package/manual/examples.authentication.md +0 -205
- package/manual/examples.md +0 -153
- package/manual/installation.md +0 -33
- package/manual/js/sandbox.js +0 -26
- package/src/ImageHandler.js +0 -134
- package/src/Mapcreator.js +0 -703
- package/src/PaginatedResourceListing.js +0 -300
- package/src/RequestParameters.js +0 -711
- package/src/ResourceLister.js +0 -368
- package/src/enums/DeletedState.js +0 -49
- package/src/enums/Enum.js +0 -130
- package/src/enums/JobShareVisibility.js +0 -43
- package/src/enums/ResultStatus.js +0 -49
- package/src/enums/index.js +0 -36
- package/src/errors/AbstractError.js +0 -70
- package/src/errors/ApiError.js +0 -139
- package/src/errors/GeoError.js +0 -36
- package/src/errors/NodeError.js +0 -36
- package/src/errors/OAuthError.js +0 -71
- package/src/errors/StaticClassError.js +0 -37
- package/src/errors/ValidationError.js +0 -164
- package/src/errors/index.js +0 -39
- package/src/index.js +0 -75
- package/src/oauth/DummyFlow.js +0 -63
- package/src/oauth/ImplicitFlow.js +0 -226
- package/src/oauth/ImplicitFlowPopup.js +0 -122
- package/src/oauth/OAuth.js +0 -131
- package/src/oauth/OAuthToken.js +0 -175
- package/src/oauth/PasswordFlow.js +0 -164
- package/src/oauth/StateContainer.js +0 -111
- package/src/proxy/GeoResourceProxy.js +0 -137
- package/src/proxy/OrganisationProxy.js +0 -149
- package/src/proxy/OwnedResourceProxy.js +0 -148
- package/src/proxy/ResourceProxy.js +0 -101
- package/src/proxy/SimpleResourceProxy.js +0 -188
- package/src/proxy/index.js +0 -37
- package/src/resources/Choropleth.js +0 -66
- package/src/resources/Color.js +0 -46
- package/src/resources/Contract.js +0 -42
- package/src/resources/Dimension.js +0 -42
- package/src/resources/DimensionSet.js +0 -56
- package/src/resources/Domain.js +0 -42
- package/src/resources/Faq.js +0 -42
- package/src/resources/Feature.js +0 -47
- package/src/resources/Font.js +0 -43
- package/src/resources/FontFamily.js +0 -55
- package/src/resources/Highlight.js +0 -39
- package/src/resources/InsetMap.js +0 -49
- package/src/resources/Job.js +0 -160
- package/src/resources/JobResult.js +0 -184
- package/src/resources/JobRevision.js +0 -201
- package/src/resources/JobShare.js +0 -61
- package/src/resources/JobType.js +0 -50
- package/src/resources/Language.js +0 -51
- package/src/resources/Layer.js +0 -48
- package/src/resources/LayerFaq.js +0 -47
- package/src/resources/LayerGroup.js +0 -57
- package/src/resources/Mapstyle.js +0 -45
- package/src/resources/MapstyleSet.js +0 -65
- package/src/resources/MapstyleSetColor.js +0 -51
- package/src/resources/Message.js +0 -94
- package/src/resources/MessageVariant.js +0 -37
- package/src/resources/Notification.js +0 -39
- package/src/resources/Organisation.js +0 -233
- package/src/resources/OrganisationNote.js +0 -57
- package/src/resources/Permission.js +0 -39
- package/src/resources/ProductTour.js +0 -53
- package/src/resources/ProductTourStep.js +0 -48
- package/src/resources/Role.js +0 -58
- package/src/resources/Svg.js +0 -39
- package/src/resources/SvgSet.js +0 -55
- package/src/resources/Tag.js +0 -50
- package/src/resources/TagType.js +0 -56
- package/src/resources/User.js +0 -251
- package/src/resources/VectorChoropleth.js +0 -40
- package/src/resources/VectorHighlight.js +0 -40
- package/src/resources/base/CrudBase.js +0 -204
- package/src/resources/base/CrudSetBase.js +0 -83
- package/src/resources/base/CrudSetItemBase.js +0 -82
- package/src/resources/base/DownloadedResource.js +0 -165
- package/src/resources/base/ResourceBase.js +0 -484
- package/src/resources/index.js +0 -81
- package/src/storage/CookiesDriver.js +0 -136
- package/src/storage/DataStoreContract.js +0 -111
- package/src/storage/DummyDriver.js +0 -91
- package/src/storage/FileDriver.js +0 -174
- package/src/storage/LocalStorageDriver.js +0 -108
- package/src/storage/StorageManager.js +0 -109
- package/src/traits/HandlesImages.js +0 -50
- package/src/traits/Injectable.js +0 -221
- package/src/traits/OwnableResource.js +0 -56
- package/src/traits/Trait.js +0 -43
- package/src/utils/Logger.js +0 -137
- package/src/utils/Singleton.js +0 -49
- package/src/utils/StaticClass.js +0 -43
- package/src/utils/Unobservable.js +0 -47
- package/src/utils/base64.js +0 -93
- package/src/utils/geo.js +0 -139
- package/src/utils/hash.js +0 -72
- package/src/utils/helpers.js +0 -178
- package/src/utils/node.js +0 -55
- package/src/utils/reflection.js +0 -170
- package/src/utils/requests.js +0 -120
- package/src/utils/uuid.js +0 -68
package/src/index.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export * from './api/choropleth.js';
|
|
2
|
+
export * from './api/color.js';
|
|
3
|
+
export * from './api/dimension.js';
|
|
4
|
+
export * from './api/dimensionSet.js';
|
|
5
|
+
export * from './api/feature.js';
|
|
6
|
+
export * from './api/font.js';
|
|
7
|
+
export * from './api/fontFamily.js';
|
|
8
|
+
export * from './api/highlight.js';
|
|
9
|
+
export * from './api/job.js';
|
|
10
|
+
export * from './api/jobResult.js';
|
|
11
|
+
export * from './api/jobRevision.js';
|
|
12
|
+
export * from './api/jobShare.js';
|
|
13
|
+
export * from './api/jobType.js';
|
|
14
|
+
export * from './api/language.js';
|
|
15
|
+
export * from './api/layer.js';
|
|
16
|
+
export * from './api/layerFaq.js';
|
|
17
|
+
export * from './api/layerGroup.js';
|
|
18
|
+
export * from './api/mapstyleSet.js';
|
|
19
|
+
export * from './api/message.js';
|
|
20
|
+
export * from './api/organisation.js';
|
|
21
|
+
export * from './api/resources.js';
|
|
22
|
+
export * from './api/svg.js';
|
|
23
|
+
export * from './api/svgSet.js';
|
|
24
|
+
export * from './api/user.js';
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
type ApiCommon,
|
|
28
|
+
type ApiCommonData,
|
|
29
|
+
type ApiError,
|
|
30
|
+
type ApiSuccess,
|
|
31
|
+
type ExtraOptions,
|
|
32
|
+
type Flatten,
|
|
33
|
+
type Revivers,
|
|
34
|
+
lastJobRevision,
|
|
35
|
+
myOrganisations,
|
|
36
|
+
myUser,
|
|
37
|
+
APIError,
|
|
38
|
+
HTTPError,
|
|
39
|
+
NetworkError,
|
|
40
|
+
getSearchParams,
|
|
41
|
+
request,
|
|
42
|
+
} from './utils.js';
|
package/src/oauth.ts
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
export let apiHost = '';
|
|
2
|
+
|
|
3
|
+
export let token: {
|
|
4
|
+
type: string;
|
|
5
|
+
token: string;
|
|
6
|
+
expires: Date;
|
|
7
|
+
|
|
8
|
+
toString: () => string;
|
|
9
|
+
} | null = null;
|
|
10
|
+
|
|
11
|
+
let apiClientId = '';
|
|
12
|
+
let callbackUrl = '';
|
|
13
|
+
let oauthScopes = ['*'];
|
|
14
|
+
|
|
15
|
+
const anchorParams = ['access_token', 'token_type', 'expires_in', 'state'];
|
|
16
|
+
|
|
17
|
+
const storagePrefix = '_m4n_';
|
|
18
|
+
const statePrefix = 'oauth_state_';
|
|
19
|
+
const storageName = 'api_token';
|
|
20
|
+
|
|
21
|
+
interface AnchorToken {
|
|
22
|
+
access_token: string;
|
|
23
|
+
token_type: string;
|
|
24
|
+
expires_in: string;
|
|
25
|
+
state: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const titleCase = (str: unknown): string => String(str).toLowerCase().replace(/\b\w/g, c => c.toUpperCase());
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Setup internal structures to use implicit authentication flow
|
|
32
|
+
*
|
|
33
|
+
* @param {string} apiUrl - Full API URL
|
|
34
|
+
* @param {string} clientId - OAuth client id
|
|
35
|
+
* @param {string} [redirectUrl] - Callback URL
|
|
36
|
+
* @param {string[]} [scopes] - A list of required scopes
|
|
37
|
+
*/
|
|
38
|
+
export function initImplicitFlow(apiUrl: string, clientId: string, redirectUrl = '', scopes = ['*']): void {
|
|
39
|
+
apiHost = apiUrl.replace(/\/+$/, '');
|
|
40
|
+
|
|
41
|
+
apiClientId = String(clientId);
|
|
42
|
+
callbackUrl = String(redirectUrl || window.location.href.split('#')[0]);
|
|
43
|
+
oauthScopes = scopes;
|
|
44
|
+
|
|
45
|
+
{
|
|
46
|
+
const key = `${storagePrefix}${storageName}`;
|
|
47
|
+
const data = window.localStorage.getItem(key);
|
|
48
|
+
|
|
49
|
+
if (data) {
|
|
50
|
+
try {
|
|
51
|
+
const obj = JSON.parse(data) as { type?: unknown; token?: unknown; expires?: unknown };
|
|
52
|
+
|
|
53
|
+
if (
|
|
54
|
+
typeof obj.type === 'string' &&
|
|
55
|
+
typeof obj.token === 'string' &&
|
|
56
|
+
typeof obj.expires === 'string' &&
|
|
57
|
+
new Date(obj.expires) > new Date()
|
|
58
|
+
) {
|
|
59
|
+
token = {
|
|
60
|
+
type: titleCase(obj.type),
|
|
61
|
+
token: obj.token,
|
|
62
|
+
expires: new Date(obj.expires),
|
|
63
|
+
|
|
64
|
+
toString(): string {
|
|
65
|
+
return `${this.type} ${this.token}`;
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
window.localStorage.removeItem(key);
|
|
70
|
+
}
|
|
71
|
+
} catch (e) {
|
|
72
|
+
/* */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
{
|
|
78
|
+
const obj = getAnchorToken();
|
|
79
|
+
|
|
80
|
+
if (isAnchorToken(obj)) {
|
|
81
|
+
// We'll not go there if anchor contains error and/or message
|
|
82
|
+
// This means that anchor parameters will be preserved for the next processing
|
|
83
|
+
cleanAnchorParams();
|
|
84
|
+
|
|
85
|
+
const expires = new Date(Date.now() + Number(obj.expires_in) * 1000);
|
|
86
|
+
|
|
87
|
+
if (isValidState(obj.state) && expires > new Date()) {
|
|
88
|
+
token = {
|
|
89
|
+
type: titleCase(obj.token_type),
|
|
90
|
+
token: obj.access_token,
|
|
91
|
+
expires,
|
|
92
|
+
|
|
93
|
+
toString(): string {
|
|
94
|
+
return `${this.type} ${this.token}`;
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const key = `${storagePrefix}${storageName}`;
|
|
99
|
+
const data = { type: token.type, token: token.token, expires: expires.toUTCString() };
|
|
100
|
+
|
|
101
|
+
window.localStorage.setItem(key, JSON.stringify(data));
|
|
102
|
+
} else {
|
|
103
|
+
// TODO: add some logic to handle this
|
|
104
|
+
// throw Error('Invalid state in url');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (authenticated()) {
|
|
110
|
+
const href = sessionStorage.getItem('redirect-url');
|
|
111
|
+
|
|
112
|
+
if (href) {
|
|
113
|
+
sessionStorage.removeItem('redirect-url');
|
|
114
|
+
window.history.replaceState(null, document.title, href);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export function authenticate(): string | never {
|
|
120
|
+
if (token && authenticated()) {
|
|
121
|
+
return token.toString();
|
|
122
|
+
} else if (anchorContainsError()) {
|
|
123
|
+
const err = getError();
|
|
124
|
+
|
|
125
|
+
cleanAnchorParams();
|
|
126
|
+
throw err;
|
|
127
|
+
} else {
|
|
128
|
+
forget();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
sessionStorage.setItem('redirect-url', window.location.href);
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
134
|
+
return window.location.assign(buildRedirectUrl()) as never;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function authenticated(): boolean {
|
|
138
|
+
return token != null && token.expires > new Date();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export async function logout(): Promise<void> {
|
|
142
|
+
if (token) {
|
|
143
|
+
await fetch(`${apiHost}/oauth/logout`, {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: {
|
|
146
|
+
Accept: 'application/json',
|
|
147
|
+
Authorization: token.toString(),
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
forget();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function forget(): void {
|
|
156
|
+
for (let i = 0; i < window.localStorage.length; ++i) {
|
|
157
|
+
const key = window.localStorage.key(i);
|
|
158
|
+
|
|
159
|
+
if (key?.startsWith(storagePrefix)) {
|
|
160
|
+
window.localStorage.removeItem(key);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
token = null;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function buildRedirectUrl(): string {
|
|
168
|
+
const queryParams = new URLSearchParams({
|
|
169
|
+
client_id: apiClientId,
|
|
170
|
+
redirect_uri: callbackUrl,
|
|
171
|
+
response_type: 'token',
|
|
172
|
+
scope: oauthScopes.join(' '),
|
|
173
|
+
state: generateState(),
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
return `${apiHost}/oauth/authorize?${queryParams}`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function getAnchorQuery(): string {
|
|
180
|
+
return window.location.hash.replace(/^#\/?/, '');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function getAnchorParams(): Record<string, unknown> {
|
|
184
|
+
const query = getAnchorQuery();
|
|
185
|
+
// eslint-disable-next-line @stylistic/padding-line-between-statements,@typescript-eslint/no-unsafe-return
|
|
186
|
+
return Object.fromEntries(query.split('&').map(pair => pair.split('=').map(decodeURIComponent)));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function getAnchorToken(): Partial<AnchorToken> {
|
|
190
|
+
const params = getAnchorParams();
|
|
191
|
+
|
|
192
|
+
return Object.fromEntries(Object.entries(params).filter(([key]) => anchorParams.includes(key)));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function isAnchorToken(anchorToken: Partial<AnchorToken>): anchorToken is AnchorToken {
|
|
196
|
+
const queryKeys = Object.keys(anchorToken);
|
|
197
|
+
|
|
198
|
+
return anchorParams.every(key => queryKeys.includes(key));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function cleanAnchorParams(): void {
|
|
202
|
+
const query = window.location.hash.replace(/^#\/?/, '');
|
|
203
|
+
const targets = [...anchorParams, 'error', 'message'];
|
|
204
|
+
const newHash = query
|
|
205
|
+
.split('&')
|
|
206
|
+
.filter(pair => !targets.includes(decodeURIComponent(pair.split('=')[0])))
|
|
207
|
+
.join('&');
|
|
208
|
+
|
|
209
|
+
if (newHash) {
|
|
210
|
+
window.location.hash = newHash;
|
|
211
|
+
} else {
|
|
212
|
+
const { origin, pathname, search } = window.location;
|
|
213
|
+
|
|
214
|
+
window.history.replaceState(null, document.title, `${origin}${pathname}${search}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function isValidState(state: string): boolean {
|
|
219
|
+
const key = `${storagePrefix}${statePrefix}${state}`;
|
|
220
|
+
const found = window.localStorage.getItem(key) != null;
|
|
221
|
+
|
|
222
|
+
if (found) {
|
|
223
|
+
window.localStorage.removeItem(key);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return found;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function anchorContainsError(): boolean {
|
|
230
|
+
return 'error' in getAnchorParams();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function generateState(): string {
|
|
234
|
+
// @ts-expect-error TS2365
|
|
235
|
+
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
236
|
+
const state = (([1e7] + -1e3 + -4e3 + -8e3 + -1e11) as string).replace(
|
|
237
|
+
/[018]/g, // @ts-expect-error TS2362
|
|
238
|
+
c => (c ^ ((Math.random() * 256) & (0x0f >>> (c >>> 2)))).toString(16),
|
|
239
|
+
);
|
|
240
|
+
const key = `${storagePrefix}${statePrefix}${state}`;
|
|
241
|
+
|
|
242
|
+
window.localStorage.setItem(key, `${Date.now()}`);
|
|
243
|
+
|
|
244
|
+
return state;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
class OAuthError extends Error {
|
|
248
|
+
error: string;
|
|
249
|
+
|
|
250
|
+
constructor(message: string, error: unknown) {
|
|
251
|
+
super(message);
|
|
252
|
+
|
|
253
|
+
this.error = String(error);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
toString(): string {
|
|
257
|
+
let error = this.error;
|
|
258
|
+
|
|
259
|
+
if (error.includes('_')) {
|
|
260
|
+
error = error.replace('_', ' ').replace(/^./, c => c.toUpperCase());
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return this.message ? `${error}: ${this.message}` : error;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function getError(): OAuthError {
|
|
268
|
+
const params = getAnchorParams();
|
|
269
|
+
|
|
270
|
+
return params.message
|
|
271
|
+
? new OAuthError(params.message as string, params.error)
|
|
272
|
+
: new OAuthError(titleCase(params.error), params.error);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Our goal is to support even obsolete platforms (ES2017+ / Node.js 8.10+).
|
|
277
|
+
* This is a small polyfill for possibly missing method used in our codebase.
|
|
278
|
+
*/
|
|
279
|
+
if (!Object.fromEntries) { // eslint-disable-next-line arrow-body-style
|
|
280
|
+
Object.fromEntries = <T = never>(entries: Iterable<readonly [string | number, T]>): { [k: string]: T } => {
|
|
281
|
+
return Array.from(entries).reduce<{ [k: string]: T }>(
|
|
282
|
+
(object, entry) => {
|
|
283
|
+
if (!Array.isArray(entry)) {
|
|
284
|
+
throw new TypeError(`Iterator value ${entry as unknown as string} is not an entry object.`);
|
|
285
|
+
}
|
|
286
|
+
object[`${entry[0]}`] = entry[1];
|
|
287
|
+
|
|
288
|
+
return object;
|
|
289
|
+
}, {}
|
|
290
|
+
);
|
|
291
|
+
};
|
|
292
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import type { CamelCasedProperties, SnakeCasedProperties } from 'type-fest';
|
|
2
|
+
import { apiHost, authenticate, token } from './oauth.js';
|
|
3
|
+
|
|
4
|
+
export type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;
|
|
5
|
+
|
|
6
|
+
export type ApiCommonData = {
|
|
7
|
+
created_at: string | null;
|
|
8
|
+
deleted_at: string | null;
|
|
9
|
+
updated_at: string | null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export interface ApiSuccess {
|
|
13
|
+
success: true;
|
|
14
|
+
data?: Record<string, unknown> | Array<Record<string, unknown>> | string | string[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ApiError {
|
|
18
|
+
success: false;
|
|
19
|
+
error: {
|
|
20
|
+
type: string;
|
|
21
|
+
message: string;
|
|
22
|
+
validation_errors?: Record<string, string[]>;
|
|
23
|
+
// schema_errors?: Record<string, unknown>[];
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type ApiCommon = ApiSuccess | ApiError;
|
|
28
|
+
|
|
29
|
+
export const myUser = 'me';
|
|
30
|
+
export const myOrganisations = 'mine';
|
|
31
|
+
export const lastJobRevision = 'last';
|
|
32
|
+
|
|
33
|
+
export const defaultListHeader = { 'X-Per-Page': '50' };
|
|
34
|
+
export const deletedNoneParam = getSearchParams({ deleted: 'none' });
|
|
35
|
+
|
|
36
|
+
export const keysToRemove = ['created_at', 'deleted_at', 'updated_at'];
|
|
37
|
+
export const staticContext = { keysToRemove: new Set(keysToRemove), keysToAdd: [], revivers: {} };
|
|
38
|
+
|
|
39
|
+
// class AuthorizationError extends Error {}
|
|
40
|
+
export class NetworkError extends Error {}
|
|
41
|
+
|
|
42
|
+
export class HTTPError extends Error {
|
|
43
|
+
statusCode: number;
|
|
44
|
+
constructor(response: Response) {
|
|
45
|
+
super(response.statusText);
|
|
46
|
+
this.statusCode = response.status;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class APIError extends Error {
|
|
51
|
+
code: string;
|
|
52
|
+
constructor(apiError: ApiError) {
|
|
53
|
+
super(apiError.error.message);
|
|
54
|
+
this.code = apiError.error.type;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function getSearchParams(search: Record<string, unknown>): URLSearchParams {
|
|
59
|
+
return new URLSearchParams(
|
|
60
|
+
Object.entries(search).reduce<string[][]>((arr, [key, value]) => {
|
|
61
|
+
if (Array.isArray(value)) {
|
|
62
|
+
arr.push(...value.map(val => [`${key}[]`, String(val)]));
|
|
63
|
+
} else if (value !== null && typeof value === 'object') {
|
|
64
|
+
const params = getSearchParams(value as Record<string, unknown>);
|
|
65
|
+
|
|
66
|
+
arr.push(
|
|
67
|
+
...Array.from(params.entries()).map(([subKey, val]) => [
|
|
68
|
+
~subKey.indexOf('[')
|
|
69
|
+
? `${key}[${subKey.slice(0, subKey.indexOf('['))}]${subKey.slice(subKey.indexOf('['))}`
|
|
70
|
+
: `${key}[${subKey}]`,
|
|
71
|
+
val,
|
|
72
|
+
]),
|
|
73
|
+
);
|
|
74
|
+
} else {
|
|
75
|
+
arr.push([key, String(value)]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return arr;
|
|
79
|
+
}, []),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type Revivers<
|
|
84
|
+
I extends ApiCommon,
|
|
85
|
+
O extends Record<string, unknown>,
|
|
86
|
+
R = Exclude<Flatten<Exclude<Exclude<I, ApiError>['data'], string | undefined>>, string>,
|
|
87
|
+
> = {
|
|
88
|
+
[K in keyof O | keyof R]?: K extends keyof O & keyof R
|
|
89
|
+
? ((data: R) => O[K]) | undefined
|
|
90
|
+
: K extends Exclude<keyof O, keyof R>
|
|
91
|
+
? (data: R) => O[K]
|
|
92
|
+
: K extends Exclude<keyof R, keyof O>
|
|
93
|
+
? undefined
|
|
94
|
+
: never;
|
|
95
|
+
};
|
|
96
|
+
export interface ExtraOptions<I extends ApiCommon, O extends Record<string, unknown> | string> {
|
|
97
|
+
method?: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; // 'CONNECT' | 'OPTIONS' | 'TRACE'
|
|
98
|
+
revivers?: O extends Record<string, unknown> ? Revivers<I, O> : never;
|
|
99
|
+
sendNull?: boolean;
|
|
100
|
+
withMeta?: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export class APIMeta<
|
|
104
|
+
I extends ApiCommon,
|
|
105
|
+
O extends Record<string, unknown> | string,
|
|
106
|
+
A = Exclude<I, ApiError>['data'] extends unknown[] ? true : false,
|
|
107
|
+
> extends Error {
|
|
108
|
+
data: A extends true ? O[] : O;
|
|
109
|
+
status: number;
|
|
110
|
+
headers: Headers;
|
|
111
|
+
|
|
112
|
+
constructor(data: A extends true ? O[] : O, headers: Headers, status: number) {
|
|
113
|
+
super();
|
|
114
|
+
|
|
115
|
+
this.data = data;
|
|
116
|
+
this.status = status;
|
|
117
|
+
this.headers = headers;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export async function request<
|
|
122
|
+
I extends ApiCommon,
|
|
123
|
+
O extends Record<string, unknown> | string,
|
|
124
|
+
A = Exclude<I, ApiError>['data'] extends unknown[] ? true : false,
|
|
125
|
+
>(
|
|
126
|
+
path: string,
|
|
127
|
+
body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null,
|
|
128
|
+
extraHeaders?: Record<string, string> | null,
|
|
129
|
+
extraOptions?: ExtraOptions<I, O>,
|
|
130
|
+
): Promise<A extends true ? O[] : O> {
|
|
131
|
+
type R = A extends true ? O[] : O;
|
|
132
|
+
|
|
133
|
+
const href = `${apiHost}${path}`;
|
|
134
|
+
const init = getRequestInit(body, extraHeaders, extraOptions);
|
|
135
|
+
|
|
136
|
+
const response = await fetch(href, init).catch((error: Error) => {
|
|
137
|
+
throw new NetworkError(error?.message ?? error);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (response.ok) {
|
|
141
|
+
const json = (await response.json().catch(() => ({
|
|
142
|
+
success: false,
|
|
143
|
+
error: { type: 'SyntaxError', message: 'Malformed JSON response' },
|
|
144
|
+
}))) as I;
|
|
145
|
+
|
|
146
|
+
if (json.success) {
|
|
147
|
+
const { data } = json;
|
|
148
|
+
|
|
149
|
+
const withMeta = extraOptions?.withMeta;
|
|
150
|
+
const revivers = extraOptions?.revivers;
|
|
151
|
+
const keys = revivers ? Object.keys(revivers) : [];
|
|
152
|
+
|
|
153
|
+
const context =
|
|
154
|
+
revivers && keys.length
|
|
155
|
+
? getContext(revivers as Revivers<I, Record<string, unknown>>, keys)
|
|
156
|
+
: staticContext;
|
|
157
|
+
|
|
158
|
+
let result: R;
|
|
159
|
+
|
|
160
|
+
if (Array.isArray(data)) {
|
|
161
|
+
let moreData = [] as unknown as R;
|
|
162
|
+
const headers = response.headers;
|
|
163
|
+
// @ts-expect-error TS2362, get valid number or 0
|
|
164
|
+
const total = headers.get('X-Paginate-Total') | 0;
|
|
165
|
+
|
|
166
|
+
if (!withMeta && ((data.length && total > data.length) || response.status === 206)) {
|
|
167
|
+
// @ts-expect-error TS2362, get valid number or 0
|
|
168
|
+
const offset = `${(headers.get('X-Paginate-Offset') | 0) + data.length}`;
|
|
169
|
+
|
|
170
|
+
moreData = await request<I, O, A>(
|
|
171
|
+
path, body, { ...extraHeaders, 'X-Offset': offset }, extraOptions,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (data.length) {
|
|
176
|
+
result = (
|
|
177
|
+
typeof data[0] !== 'string'
|
|
178
|
+
? (data as Array<Record<string, unknown>>).map(processData, context)
|
|
179
|
+
: data
|
|
180
|
+
).concat(moreData) as R;
|
|
181
|
+
} else {
|
|
182
|
+
result = moreData;
|
|
183
|
+
}
|
|
184
|
+
} else {
|
|
185
|
+
if (data !== undefined) {
|
|
186
|
+
// @ts-expect-error TS2345, TODO: fix type error for the `context` object
|
|
187
|
+
result = (typeof data !== 'string' ? processData.call(context, data) : data) as R;
|
|
188
|
+
} else {
|
|
189
|
+
result = {} as R;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (withMeta) {
|
|
194
|
+
throw new APIMeta<I, O, A>(result, response.headers, response.status);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return result;
|
|
198
|
+
} else {
|
|
199
|
+
throw new APIError(json);
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
// TODO: parse and process all typical errors
|
|
203
|
+
// eslint-disable-next-line default-case
|
|
204
|
+
switch (response.status) {
|
|
205
|
+
case 401:
|
|
206
|
+
authenticate();
|
|
207
|
+
break; // NO-OP
|
|
208
|
+
case 403:
|
|
209
|
+
case 404:
|
|
210
|
+
case 406:
|
|
211
|
+
throw new APIError(
|
|
212
|
+
(await response.json().catch(() => ({
|
|
213
|
+
success: false,
|
|
214
|
+
error: { type: 'HttpException', message: response.statusText },
|
|
215
|
+
}))) as ApiError,
|
|
216
|
+
);
|
|
217
|
+
case 429:
|
|
218
|
+
await new Promise(
|
|
219
|
+
(
|
|
220
|
+
resolve, // @ts-expect-error TS2531
|
|
221
|
+
) => { setTimeout(resolve, response.headers.get('X-RateLimit-Reset') * 1000 || 500) },
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
return request<I, O, A>(path, body, extraHeaders, extraOptions);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
throw new HTTPError(response);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function getRequestInit<I extends ApiCommon, O extends Record<string, unknown>>(
|
|
232
|
+
body?: XMLHttpRequestBodyInit | Record<string | number, unknown> | null,
|
|
233
|
+
extraHeaders?: Record<string, string> | null,
|
|
234
|
+
extraOptions?: ExtraOptions<I, O>,
|
|
235
|
+
): RequestInit {
|
|
236
|
+
const authorization = token ? { Authorization: token.toString() } : null;
|
|
237
|
+
let contentType = null as { 'Content-Type': string } | null;
|
|
238
|
+
|
|
239
|
+
if (body !== undefined) {
|
|
240
|
+
switch (true) {
|
|
241
|
+
case typeof body === 'string':
|
|
242
|
+
contentType = { 'Content-Type': 'text/plain' };
|
|
243
|
+
break;
|
|
244
|
+
case body instanceof FormData: // Autofilled with 'multipart/form-data'
|
|
245
|
+
case body instanceof URLSearchParams: // Autofilled with 'application/x-www-form-urlencoded'
|
|
246
|
+
break;
|
|
247
|
+
case body instanceof Blob: // File is instance of Blob too
|
|
248
|
+
contentType = { 'Content-Type': body.type || 'application/octet-stream' };
|
|
249
|
+
break;
|
|
250
|
+
case body instanceof ArrayBuffer:
|
|
251
|
+
case ArrayBuffer.isView(body):
|
|
252
|
+
contentType = { 'Content-Type': 'application/octet-stream' };
|
|
253
|
+
break;
|
|
254
|
+
case body === null && !extraOptions?.sendNull:
|
|
255
|
+
break;
|
|
256
|
+
default:
|
|
257
|
+
contentType = { 'Content-Type': 'application/json' };
|
|
258
|
+
body = JSON.stringify(body);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const headers = { Accept: 'application/json', ...authorization, ...contentType, ...extraHeaders };
|
|
263
|
+
const method = extraOptions?.method ?? (body != null ? 'POST' : 'GET'); // don't touch `!=` please
|
|
264
|
+
|
|
265
|
+
return { body, headers, method } as RequestInit;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
interface Context<I extends ApiCommon, O extends Record<string, unknown>> {
|
|
269
|
+
keysToRemove: Set<string>;
|
|
270
|
+
keysToAdd: string[];
|
|
271
|
+
revivers: Revivers<I, O>;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function getContext<I extends ApiCommon, O extends Record<string, unknown>>(
|
|
275
|
+
revivers: Revivers<I, O>,
|
|
276
|
+
keys = Object.keys(revivers),
|
|
277
|
+
): Context<I, O> {
|
|
278
|
+
return {
|
|
279
|
+
keysToRemove: new Set(keys.filter(isUndefined, revivers).concat(keysToRemove)),
|
|
280
|
+
keysToAdd: keys.filter(isReviver, revivers),
|
|
281
|
+
revivers,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function processData<I extends ApiCommon, O extends Record<string, unknown>>(
|
|
286
|
+
this: Context<I, O>,
|
|
287
|
+
data: Exclude<Flatten<Exclude<Exclude<I, ApiError>['data'], string | undefined>>, string>,
|
|
288
|
+
): O { /* eslint-disable @typescript-eslint/prefer-for-of */
|
|
289
|
+
const result = {} as Record<string, unknown>;
|
|
290
|
+
|
|
291
|
+
const keys = Object.keys(data).filter(isPreserved, this.keysToRemove);
|
|
292
|
+
|
|
293
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
294
|
+
result[toCamelCase(keys[i])] = data[keys[i]];
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (this.keysToAdd.length) {
|
|
298
|
+
const keys = this.keysToAdd;
|
|
299
|
+
|
|
300
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
301
|
+
result[keys[i]] = this.revivers[keys[i]]!(data);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return result as O;
|
|
306
|
+
} /* eslint-enable @typescript-eslint/prefer-for-of */
|
|
307
|
+
|
|
308
|
+
export function toApiType<T extends Record<string, unknown>>(body: T): SnakeCasedProperties<T> {
|
|
309
|
+
return Object.fromEntries(
|
|
310
|
+
Object.entries(body).map(([k, v]) => [toSnakeCase(k), v]),
|
|
311
|
+
) as SnakeCasedProperties<T>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function toAppType<T extends Record<string, unknown>>(body: T): CamelCasedProperties<T> {
|
|
315
|
+
return Object.fromEntries(
|
|
316
|
+
Object.entries(body).map(([k, v]) => [toCamelCase(k), v]),
|
|
317
|
+
) as CamelCasedProperties<T>;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
export function ensureArray<T extends Record<string, unknown>>(data: T | T[]): T[] {
|
|
321
|
+
return Array.isArray(data) ? data : [data];
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function toCamelCase(key: string): string {
|
|
325
|
+
return key.replace(/_+(.)/g, (_, c: string) => c.toUpperCase());
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function toSnakeCase(key: string): string {
|
|
329
|
+
return key.replace(/[A-Z]/g, '_$&').toLowerCase();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function isUndefined(this: Record<string, unknown>, key: string): boolean {
|
|
333
|
+
return this[key] === undefined;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function isReviver(this: Record<string, unknown>, key: string): boolean {
|
|
337
|
+
return this[key] !== undefined;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function isPreserved(this: Set<string>, key: string): boolean {
|
|
341
|
+
return !this.has(key);
|
|
342
|
+
}
|