@vannizhang/living-atlas-content-validator 1.5.16 → 1.5.18-beta.1

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.
Files changed (197) hide show
  1. package/README.md +1376 -162
  2. package/dist/configureSettings.d.ts +133 -0
  3. package/dist/configureSettings.js +61 -0
  4. package/dist/configureSettings.js.map +1 -0
  5. package/dist/data/TitleSummaryMatchingPatterns_Locations.json +829 -0
  6. package/dist/data/TitleSummaryMatchingPatterns_Sources.json +382 -0
  7. package/dist/data/TitleSummaryMatchingPatterns_Time.json +25 -0
  8. package/dist/data/TitleSummaryMatchingPatterns_Topics.json +1365 -0
  9. package/dist/data/TitleSummaryRejectedPatterns.json +44 -0
  10. package/dist/index.d.ts +27 -9
  11. package/dist/index.js +55 -9
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/accessInformation/isValidAccessInformation.js +4 -6
  14. package/dist/lib/accessInformation/isValidAccessInformation.js.map +1 -1
  15. package/dist/lib/checkProfanities/checkProfanities.d.ts +7 -0
  16. package/dist/lib/checkProfanities/checkProfanities.js +26 -0
  17. package/dist/lib/checkProfanities/checkProfanities.js.map +1 -0
  18. package/dist/lib/checkTitleAndSnippetSearchability/checkTitleAndSnippetSearchability.d.ts +34 -0
  19. package/dist/lib/{recommendedText/checkRecommendedText.js → checkTitleAndSnippetSearchability/checkTitleAndSnippetSearchability.js} +51 -25
  20. package/dist/lib/checkTitleAndSnippetSearchability/checkTitleAndSnippetSearchability.js.map +1 -0
  21. package/dist/lib/checkTitleAndSnippetSearchability/config.d.ts +97 -0
  22. package/dist/lib/checkTitleAndSnippetSearchability/config.js +41 -0
  23. package/dist/lib/checkTitleAndSnippetSearchability/config.js.map +1 -0
  24. package/dist/lib/checkTitleAndSnippetSearchability/data.d.ts +0 -0
  25. package/dist/lib/checkTitleAndSnippetSearchability/data.js +693 -0
  26. package/dist/lib/checkTitleAndSnippetSearchability/data.js.map +1 -0
  27. package/dist/lib/checkTitleAndSnippetSearchability/helpers.d.ts +117 -0
  28. package/dist/lib/checkTitleAndSnippetSearchability/helpers.js +241 -0
  29. package/dist/lib/checkTitleAndSnippetSearchability/helpers.js.map +1 -0
  30. package/dist/lib/checkTitleAndSnippetSearchability/matchDateTimeInfo.d.ts +34 -0
  31. package/dist/lib/checkTitleAndSnippetSearchability/matchDateTimeInfo.js +207 -0
  32. package/dist/lib/checkTitleAndSnippetSearchability/matchDateTimeInfo.js.map +1 -0
  33. package/dist/lib/checkTitleAndSnippetSearchability/matchLocationInfo.d.ts +34 -0
  34. package/dist/lib/checkTitleAndSnippetSearchability/matchLocationInfo.js +170 -0
  35. package/dist/lib/checkTitleAndSnippetSearchability/matchLocationInfo.js.map +1 -0
  36. package/dist/lib/checkTitleAndSnippetSearchability/matchSourceInfo.d.ts +34 -0
  37. package/dist/lib/checkTitleAndSnippetSearchability/matchSourceInfo.js +172 -0
  38. package/dist/lib/checkTitleAndSnippetSearchability/matchSourceInfo.js.map +1 -0
  39. package/dist/lib/checkTitleAndSnippetSearchability/matchTopicInfo.d.ts +36 -0
  40. package/dist/lib/checkTitleAndSnippetSearchability/matchTopicInfo.js +175 -0
  41. package/dist/lib/checkTitleAndSnippetSearchability/matchTopicInfo.js.map +1 -0
  42. package/dist/lib/checkTitleAndSnippetSearchability/scoringConfig.js.map +1 -0
  43. package/dist/lib/config.d.ts +4 -1
  44. package/dist/lib/config.js +5 -5
  45. package/dist/lib/config.js.map +1 -1
  46. package/dist/lib/deleteProtection/isDeleteProtectionEnabled.js +6 -2
  47. package/dist/lib/deleteProtection/isDeleteProtectionEnabled.js.map +1 -1
  48. package/dist/lib/deprecated/isDeprecated.js +5 -2
  49. package/dist/lib/deprecated/isDeprecated.js.map +1 -1
  50. package/dist/lib/description/isValidDescription.js +8 -5
  51. package/dist/lib/description/isValidDescription.js.map +1 -1
  52. package/dist/lib/licenseInfo/isValidLicenseInfo.js +5 -2
  53. package/dist/lib/licenseInfo/isValidLicenseInfo.js.map +1 -1
  54. package/dist/lib/sharing/isValidAccess.js +5 -2
  55. package/dist/lib/sharing/isValidAccess.js.map +1 -1
  56. package/dist/lib/ssl/isValidSSL.js +15 -6
  57. package/dist/lib/ssl/isValidSSL.js.map +1 -1
  58. package/dist/lib/summary/isValidSummary.js +6 -3
  59. package/dist/lib/summary/isValidSummary.js.map +1 -1
  60. package/dist/lib/tags/isValidTags.js +7 -3
  61. package/dist/lib/tags/isValidTags.js.map +1 -1
  62. package/dist/lib/thumbnail/isValidThumbnail.d.ts +6 -1
  63. package/dist/lib/thumbnail/isValidThumbnail.js +10 -7
  64. package/dist/lib/thumbnail/isValidThumbnail.js.map +1 -1
  65. package/dist/lib/title/isValidTitle.js +9 -3
  66. package/dist/lib/title/isValidTitle.js.map +1 -1
  67. package/dist/lib/userProfileDescription/isValidUserProfileDescription.js +44 -38
  68. package/dist/lib/userProfileDescription/isValidUserProfileDescription.js.map +1 -1
  69. package/dist/lib/userProfileName/isValidUserProfileName.js +8 -5
  70. package/dist/lib/userProfileName/isValidUserProfileName.js.map +1 -1
  71. package/dist/lib/userProfileThumbnail/isValidUserProfileThumbnail.js +6 -3
  72. package/dist/lib/userProfileThumbnail/isValidUserProfileThumbnail.js.map +1 -1
  73. package/dist/lib/util/containsNonEnglishCharacters.d.ts +13 -0
  74. package/dist/lib/util/containsNonEnglishCharacters.js +30 -0
  75. package/dist/lib/util/containsNonEnglishCharacters.js.map +1 -0
  76. package/dist/lib/util/countSentences.d.ts +23 -0
  77. package/dist/lib/util/countSentences.js +54 -0
  78. package/dist/lib/util/countSentences.js.map +1 -0
  79. package/dist/lib/util/createWordBoundaryRegex.d.ts +46 -0
  80. package/dist/lib/util/createWordBoundaryRegex.js +77 -0
  81. package/dist/lib/util/createWordBoundaryRegex.js.map +1 -0
  82. package/dist/lib/util/escapeSpecialCharacters.d.ts +7 -0
  83. package/dist/lib/util/escapeSpecialCharacters.js +22 -0
  84. package/dist/lib/util/escapeSpecialCharacters.js.map +1 -0
  85. package/dist/lib/util/getLivingAtlasSupportedItemTypes.d.ts +21 -0
  86. package/dist/lib/util/getLivingAtlasSupportedItemTypes.js +34 -0
  87. package/dist/lib/util/getLivingAtlasSupportedItemTypes.js.map +1 -0
  88. package/dist/lib/util/getNumberOfWords.js +6 -2
  89. package/dist/lib/util/getNumberOfWords.js.map +1 -1
  90. package/dist/lib/util/getScoringRules.js +6 -0
  91. package/dist/lib/util/getScoringRules.js.map +1 -1
  92. package/dist/lib/util/isLayer.js +3 -2
  93. package/dist/lib/util/isLayer.js.map +1 -1
  94. package/dist/lib/util/isUrl.d.ts +6 -0
  95. package/dist/lib/util/isUrl.js +16 -1
  96. package/dist/lib/util/isUrl.js.map +1 -1
  97. package/dist/lib/util/isValidRegexPattern.d.ts +7 -0
  98. package/dist/lib/util/isValidRegexPattern.js +20 -0
  99. package/dist/lib/util/isValidRegexPattern.js.map +1 -0
  100. package/dist/lib/util/sanitizeTags.d.ts +6 -0
  101. package/dist/lib/util/sanitizeTags.js +16 -0
  102. package/dist/lib/util/sanitizeTags.js.map +1 -0
  103. package/dist/lib/util/shouldValidateByBetaRules.js +7 -1
  104. package/dist/lib/util/shouldValidateByBetaRules.js.map +1 -1
  105. package/dist/lib/util/stringsConfig.d.ts +9 -0
  106. package/dist/lib/util/stringsConfig.js +9 -1
  107. package/dist/lib/util/stringsConfig.js.map +1 -1
  108. package/dist/lib/validate/validate.d.ts +57 -12
  109. package/dist/lib/validate/validate.js +87 -213
  110. package/dist/lib/validate/validate.js.map +1 -1
  111. package/dist/lib/validate/validateHelpers.d.ts +63 -0
  112. package/dist/lib/validate/validateHelpers.js +157 -0
  113. package/dist/lib/validate/validateHelpers.js.map +1 -0
  114. package/dist/locale/de.json +1 -1
  115. package/dist/locale/en.json +23 -23
  116. package/dist/locale/es.json +1 -1
  117. package/dist/locale/fr.json +1 -1
  118. package/dist/locale/ja.json +1 -1
  119. package/dist/locale/pt-br.json +1 -1
  120. package/dist/package-info.json +1 -1
  121. package/dist/services/content-validator-assets/config.d.ts +4 -0
  122. package/dist/services/content-validator-assets/config.js +8 -0
  123. package/dist/services/content-validator-assets/config.js.map +1 -0
  124. package/dist/services/content-validator-assets/fetchAdditonalPatterns4TitleAndSnippetSearchability.d.ts +95 -0
  125. package/dist/services/content-validator-assets/fetchAdditonalPatterns4TitleAndSnippetSearchability.js +92 -0
  126. package/dist/services/content-validator-assets/fetchAdditonalPatterns4TitleAndSnippetSearchability.js.map +1 -0
  127. package/dist/services/content-validator-assets/fetchProfanitiesData.d.ts +18 -0
  128. package/dist/services/content-validator-assets/fetchProfanitiesData.js +55 -0
  129. package/dist/services/content-validator-assets/fetchProfanitiesData.js.map +1 -0
  130. package/dist/services/content-validator-assets/helpers.d.ts +16 -0
  131. package/dist/services/content-validator-assets/helpers.js +35 -0
  132. package/dist/services/content-validator-assets/helpers.js.map +1 -0
  133. package/dist/services/custom-terms/config.d.ts +27 -0
  134. package/dist/services/custom-terms/config.js +79 -0
  135. package/dist/services/custom-terms/config.js.map +1 -0
  136. package/dist/services/custom-terms/customTerms.d.ts +229 -0
  137. package/dist/services/custom-terms/customTerms.js +394 -0
  138. package/dist/services/custom-terms/customTerms.js.map +1 -0
  139. package/dist/services/custom-terms/helpers.d.ts +8 -0
  140. package/dist/services/custom-terms/helpers.js +25 -0
  141. package/dist/services/custom-terms/helpers.js.map +1 -0
  142. package/dist/services/custom-terms/index.d.ts +3 -0
  143. package/dist/services/custom-terms/index.js +10 -0
  144. package/dist/services/custom-terms/index.js.map +1 -0
  145. package/dist/services/custom-terms-review-results/config.d.ts +31 -0
  146. package/dist/services/custom-terms-review-results/config.js +78 -0
  147. package/dist/services/custom-terms-review-results/config.js.map +1 -0
  148. package/dist/services/custom-terms-review-results/customTermsReviewResults.d.ts +133 -0
  149. package/dist/services/custom-terms-review-results/customTermsReviewResults.js +276 -0
  150. package/dist/services/custom-terms-review-results/customTermsReviewResults.js.map +1 -0
  151. package/dist/services/custom-terms-review-results/helpers.d.ts +24 -0
  152. package/dist/services/custom-terms-review-results/helpers.js +52 -0
  153. package/dist/services/custom-terms-review-results/helpers.js.map +1 -0
  154. package/dist/services/custom-terms-review-results/index.d.ts +4 -0
  155. package/dist/services/custom-terms-review-results/index.js +13 -0
  156. package/dist/services/custom-terms-review-results/index.js.map +1 -0
  157. package/dist/services/shared/addFeatures.d.ts +28 -0
  158. package/dist/services/shared/addFeatures.js +52 -0
  159. package/dist/services/shared/addFeatures.js.map +1 -0
  160. package/dist/services/shared/applyEdits.d.ts +28 -0
  161. package/dist/services/shared/applyEdits.js +53 -0
  162. package/dist/services/shared/applyEdits.js.map +1 -0
  163. package/dist/services/shared/config.d.ts +44 -0
  164. package/dist/services/shared/config.js +35 -0
  165. package/dist/services/shared/config.js.map +1 -0
  166. package/dist/services/shared/getItemInfo.d.ts +36 -0
  167. package/dist/services/shared/getItemInfo.js +56 -0
  168. package/dist/services/shared/getItemInfo.js.map +1 -0
  169. package/dist/types/index.d.ts +25 -22
  170. package/package.json +7 -4
  171. package/dist/data/TitleSummaryMatchingPatterns.json +0 -1902
  172. package/dist/lib/layers/isValidLayerCount.d.ts +0 -12
  173. package/dist/lib/layers/isValidLayerCount.js +0 -171
  174. package/dist/lib/layers/isValidLayerCount.js.map +0 -1
  175. package/dist/lib/layers/scoringConfig.d.ts +0 -10
  176. package/dist/lib/layers/scoringConfig.js +0 -20
  177. package/dist/lib/layers/scoringConfig.js.map +0 -1
  178. package/dist/lib/recommendedText/checkRecommendedText.d.ts +0 -15
  179. package/dist/lib/recommendedText/checkRecommendedText.js.map +0 -1
  180. package/dist/lib/recommendedText/helpers.d.ts +0 -15
  181. package/dist/lib/recommendedText/helpers.js +0 -62
  182. package/dist/lib/recommendedText/helpers.js.map +0 -1
  183. package/dist/lib/recommendedText/matchDateTimeInfo.d.ts +0 -9
  184. package/dist/lib/recommendedText/matchDateTimeInfo.js +0 -81
  185. package/dist/lib/recommendedText/matchDateTimeInfo.js.map +0 -1
  186. package/dist/lib/recommendedText/matchLocationInfo.d.ts +0 -9
  187. package/dist/lib/recommendedText/matchLocationInfo.js +0 -745
  188. package/dist/lib/recommendedText/matchLocationInfo.js.map +0 -1
  189. package/dist/lib/recommendedText/matchSourceInfo.d.ts +0 -9
  190. package/dist/lib/recommendedText/matchSourceInfo.js +0 -32
  191. package/dist/lib/recommendedText/matchSourceInfo.js.map +0 -1
  192. package/dist/lib/recommendedText/matchTopicInfo.d.ts +0 -9
  193. package/dist/lib/recommendedText/matchTopicInfo.js +0 -32
  194. package/dist/lib/recommendedText/matchTopicInfo.js.map +0 -1
  195. package/dist/lib/recommendedText/scoringConfig.js.map +0 -1
  196. /package/dist/lib/{recommendedText → checkTitleAndSnippetSearchability}/scoringConfig.d.ts +0 -0
  197. /package/dist/lib/{recommendedText → checkTitleAndSnippetSearchability}/scoringConfig.js +0 -0
package/README.md CHANGED
@@ -1,185 +1,1398 @@
1
1
  # ArcGIS Living Atlas Content Validator
2
- This package provides validation and scoring rules for curating content in the ArcGIS Living Atlas.
3
2
 
4
- ## Background
5
- The ArcGIS Living Atlas is a collection of curated GIS content. This content is submitted for inclusion in the Living Atlas by Esri Cartographers and Data Scientists from around the world.
3
+ ![npm](https://img.shields.io/npm/v/@vannizhang/living-atlas-content-validator) ![license](https://img.shields.io/npm/l/@vannizhang/living-atlas-content-validator) ![downloads](https://img.shields.io/npm/dt/@vannizhang/living-atlas-content-validator)
6
4
 
7
- The Living Atlas consists of items in ArcGIS Online. Users can nominate items for inclusion in the Living Atlas. During the nomination process, items are validated and scored based on the completeness of the item and its metadata. The score helps to identify key characteristics of your item that will ensure others can find and understand the item.
5
+ This package provides a comprehensive set of **validation and scoring rules** designed to assist in the curation of content for the ArcGIS Living Atlas. It plays a crucial role in ensuring that nominated items meet the high-quality standards required for inclusion in the Living Atlas of the World.
6
+ The package is utilized in two key applications:
8
7
 
9
- The details page of an item in ArcGIS Online provides information about the item being shared, along with additional information to help others find and use the item. The goal is to create a well-documented item description page so that others will understand what they have found, where the data is from, and what they can expect to see when opening the item.
8
+ - **Living Atlas Nomination App** Enables item owners to validate their own content before submitting it for nomination.
9
+ - **Living Atlas Curation App** – Used by Living Atlas Curators to perform a detailed evaluation of nominated items.
10
+
11
+ The validation process evaluates whether an item meets all necessary criteria, such as metadata completeness and adherence to best practices. By enforcing these validation and scoring rules, the package helps to ensure that only high-quality, well-documented, and properly formatted content is nominated and included in the ArcGIS Living Atlas of the World.
12
+
13
+ ## Table of Contents
14
+ - [Installation](#installation)
15
+ - [Usage](#usage)
16
+ - [Configuration](#configuration)
17
+ - [API Reference](#api-reference)
18
+ - [validate](#validate)
19
+ - [isValidTitle](#isvalidtitle)
20
+ - [isValidAccessInformation](#isvalidaccessinformation)
21
+ - [isValidDescription](#isvaliddescription)
22
+ - [isValidLicenseInfo](#isvalidlicenseinfo)
23
+ - [isValidAccess](#isvalidaccess)
24
+ - [isValidSummary](#isvalidsummary)
25
+ - [isValidTags](#isvalidtags)
26
+ - [isValidThumbnail](#isvalidthumbnail)
27
+ - [isDeprecated](#isdeprecated)
28
+ - [isDeleteProtectionEnabled](#isdeleteprotectionenabled)
29
+ - [isValidUserProfileName](#isvaliduserprofilename)
30
+ - [isValidUserProfileDescription](#isvaliduserprofiledescription)
31
+ - [isValidUserProfileThumbnail](#isvaliduserprofilethumbnail)
32
+ - [checkTitleAndSnippetSearchability](#checktitleandsnippetsearchability)
33
+ - [isEligibleForCheckingTitleAndSnippetSearchability](#iseligibleforcheckingtitleandsnippetsearchability)
34
+ - [matchLocationInfo](#matchlocationinfo)
35
+ - [isRecognizedLocation](#isrecognizedlocation)
36
+ - [isRejectedLocationInfo](#isrejectedlocationinfo)
37
+ - [matchSourceInfo](#matchsourceinfo)
38
+ - [isRecognizedSource](#isrecognizedsource)
39
+ - [isRejectedSourceInfo](#isrejectedsourceinfo)
40
+ - [matchTopicInfo](#matchtopicinfo)
41
+ - [isRecognizedTopic](#isrecognizedtopic)
42
+ - [isRejectedTopicInfo](#isrejectedtopicinfo)
43
+ - [matchDateTimeInfo](#matchdatetimeinfo)
44
+ - [isRecognizedDateTimeInfo](#isrecognizeddatetimeinfo)
45
+ - [isRejectedDateTimeInfo](#isrejecteddatetimeinfo)
46
+ - [getLivingAtlasSupportedItemTypes](#getlivingatlassupporteditemtypes)
47
+ - [checkIsLivingAtlasSupportedItemType](#checkislivingatlassupporteditemtype)
48
+ - [Types](#types)
49
+ - [ValidationResult](#validationresult)
50
+ - [ValidationResultStatus](#validationresultstatus)
51
+ - [ValidationInfo](#validationinfo)
52
+ - [MatchResult](#matchresult)
53
+ - [Issues](#issues)
54
+ - [License](#license)
10
55
 
11
56
  ## Installation
12
57
 
13
- To install this Package, simply run:
58
+ Install the package using npm:
14
59
 
15
- ```shell
60
+ ```sh
16
61
  npm install @vannizhang/living-atlas-content-validator
17
62
  ```
18
63
 
19
- ## Example
20
- Here is an example of how to validate an item and the item owner's user profile in ArcGIS Online:
64
+ ## Usage
65
+
66
+ Import and use the validator in your project:
67
+
68
+ ```ts
69
+ import {
70
+ validate,
71
+ } from '@vannizhang/living-atlas-content-validator';
72
+
73
+ // ArcGIS Online Item to validate
74
+ const item = {
75
+ id: 'mock-item-id',
76
+ owner: 'mock-owner',
77
+ title: 'Mock Item Title',
78
+ snippet: 'This is a short summary of the item.',
79
+ description: 'This is a detailed description of the item.',
80
+ type: 'Web Map',
81
+ tags: ['tag1', 'tag2'],
82
+ // Other properties...
83
+ }
84
+
85
+ // User profile of the owner of the item being validated.
86
+ const userProfile = {
87
+ fullName: 'mock-owner',
88
+ description: 'mocked user profile',
89
+ thumbnail: 'thumbnail/avatar.png',
90
+ // Other properties...
91
+ }
92
+
93
+ const validationResults = validate(item, userProfile);
94
+ ```
95
+
96
+ ## Configuration
97
+
98
+ The package provides a `configureSettings` function that allows customization of language, service tier, and additional validation patterns.
99
+
100
+ ### `configureSettings(params)`
101
+ Configures the package settings including language preferences, service tier selection, and customization options for validation patterns. This function should be called before using any validation functionality to ensure the validator operates with the correct context and rule set.
102
+
103
+ **Parameters:**
104
+ - `language` (`string`, required) - The language of the library. Default is `'en'`.
105
+ Supported languages:
106
+ - `'en'` (English)
107
+ - `'de'` (German)
108
+ - `'es'` (Spanish)
109
+ - `'fr'` (French)
110
+ - `'ja'` (Japanese)
111
+ - `'pt-br'` (Brazilian Portuguese)
112
+
113
+ - `serviceTier` (`string`, required) - The service tier of the application.
114
+ - `'dev'`: Development tier, points to `devext.arcgis.com`.
115
+ - `'prod'`: Production tier, points to `www.arcgis.com`.
116
+
117
+ - `additionalPatternsForTitleAndSnippetSearchability` (*object*, optional) - Additional validation patterns for title and snippet searchability.
118
+ - `matchingPatternsLocation` (`string[]`) - List of location matching patterns.
119
+ - `rejectedPatternsLocation` (`string[]`) - List of rejected location patterns.
120
+ - `matchingPatternsSource` (`string[]`) - List of source matching patterns.
121
+ - `rejectedPatternsSource` (`string[]`) - List of rejected source patterns.
122
+ - `matchingPatternsTopic` (`string[]`) - List of topic matching patterns.
123
+ - `rejectedPatternsTopic` (`string[]`) - List of rejected topic patterns.
124
+ - `matchingPatternsYearVintage` (`string[]`) - List of matching year vintage patterns.
125
+ - `rejectedPatternsYearVintage` (`string[]`) - List of rejected year vintage patterns.
126
+ - `shouldAvoidUsingWordBoundary` (`boolean`) - Determines if word boundaries should be avoided (for non-Latin languages).
127
+
128
+ - `profanities` (`string[]`, optional) - List of words considered profane for validation.
129
+
130
+ ### Example Usage
131
+
21
132
  ```js
22
- import { validate } from ' @vannizhang/living-atlas-content-validator';
23
-
24
- const validationResult = validate(
25
- // ArcGIS Online Item
26
- {
27
- id: 'fd61b9e0c69c4e14bebd50a9a968348c',
28
- owner: 'esri',
29
- title: 'Sentinel-2 Views',
30
- snippet: 'Sentinel-2, 10m Multispectral, Multitemporal, 13-band images with visual renderings and indices...',
31
- type: 'Imagery Layer ',
32
- thumbnail: 'thumbnail/thumbnail1577152707660.jpeg',
33
- access: 'shared',
34
- description: 'Sentinel-2, 10, 20, and 60m Multispectral, Multitemporal, 13-band imagery is rendered on-the-fly and available for visualization and analytics...',
35
- // this is a custom property that provides the dimension of the thumbnail image
36
- dimension: {
37
- width: 400,
38
- height: 240
39
- }
133
+ import {
134
+ configureSettings
135
+ } from '@vannizhang/living-atlas-content-validator';
136
+
137
+ configureSettings({
138
+ language: 'en',
139
+ serviceTier: 'prod',
140
+ additionalPatternsForTitleAndSnippetSearchability: {
141
+ matchingPatternsLocation: ['New York', 'Los Angeles'],
142
+ rejectedPatternsLocation: ['Unknown', 'Unknown Location'],
143
+ matchingPatternsSource: ['NOAA', 'Department of Energy'],
144
+ rejectedPatternsSource: ['Unknown', 'Unknown Source'],
145
+ matchingPatternsTopic: ['Climate Change', 'Renewable Energy'],
146
+ rejectedPatternsTopic: ['Unknown', 'Unknown Topic'],
147
+ matchingPatternsYearVintage: ['bi-weekly', 'monthly'],
148
+ rejectedPatternsYearVintage: ['Unknown', 'Unknown Year Vintage'],
149
+ shouldAvoidUsingWordBoundary: false
40
150
  },
41
- // ArcGIS Online User Profile
42
- {
43
- fullName: 'Esri Inc.',
44
- description: 'Esri develops geographic information systems (GIS) solutions that function as an integral component in nearly every type of organization....',
45
- thumbnail: 'esri_150.jpg',
151
+ profanities: ['badword1', 'badword2']
152
+ });
153
+ ```
154
+
155
+ If `serviceTier` is not `dev` or `prod`, or if an unsupported language is provided, an error will be thrown.
156
+
157
+ ## API Reference
158
+
159
+ ### `validate`
160
+ Validates an ArcGIS Online item and its owner's user profile against Living Atlas criteria.
161
+
162
+ ```ts
163
+ import { validate } from '@vannizhang/living-atlas-content-validator';
164
+
165
+ validate(
166
+ item: IItem,
167
+ userProfile: IUser,
168
+ options?: ValidateOptions
169
+ ): ValidationResult
170
+ ```
171
+
172
+ **Parameters:**
173
+ - `item` (`IItem`, required): The ArcGIS Online item to validate.
174
+ - `userProfile` (`IUser`, required): The user profile of the item's owner.
175
+ - `options` (`ValidateOptions`, optional): Additional configuration for validation.
176
+ - `customPatternsForLocationInfo` (`string[]`, optional): Custom patterns for location information.
177
+ - `customPatternsForDataVintageInfo` (`string[]`, optional): Custom patterns for data vintage information.
178
+ - `customPatternsForSourceInfo` (`string[]`, optional): Custom patterns for source information.
179
+ - `customPatternsForTopicInfo` (`string[]`, optional): Custom patterns for topic information.
180
+ - `thumbnailDimension` (`{ width: number; height: number; }`, optional): Expected dimensions for the item's thumbnail.
181
+
182
+ **Returns:**
183
+ - `ValidationResult`: An object containing detailed validation results, a total score, and a flag indicating whether the item can be nominated to Living Atlas.
184
+
185
+ **Example:**
186
+ ```ts
187
+ import { validate } from '@vannizhang/living-atlas-content-validator';
188
+
189
+ const item = {
190
+ id: 'mock-item-id',
191
+ owner: 'mock-owner',
192
+ title: 'Mock Item Title',
193
+ snippet: 'This is a short summary of the item.',
194
+ description: 'This is a detailed description of the item.',
195
+ type: 'Web Map',
196
+ tags: ['tag1', 'tag2'],
197
+ // Other properties...
198
+ };
199
+
200
+ const userProfile = {
201
+ fullName: 'mock-owner',
202
+ description: 'mocked user profile',
203
+ thumbnail: 'thumbnail/avatar.png',
204
+ culture: 'en',
205
+ // Other properties...
206
+ };
207
+
208
+ const options = {
209
+ customPatternsForLocationInfo: ['New York','Los Angeles'],
210
+ customPatternsForDataVintageInfo: ['bi-weekly'],
211
+ customPatternsForSourceInfo: ['NOAA'],
212
+ customPatternsForTopicInfo: [ 'Climate Change' ],
213
+ thumbnailDimension: { width: 600, height: 400 },
214
+ };
215
+
216
+ const validationResults = validate(item, userProfile, options);
217
+ console.log(validationResults);
218
+ ```
219
+
220
+ ---
221
+
222
+ ### `isValidTitle`
223
+ Validates an item's title against ArcGIS Online and Living Atlas-specific rules.
224
+
225
+ ```ts
226
+ import { isValidTitle } from '@vannizhang/living-atlas-content-validator';
227
+
228
+ isValidTitle(
229
+ item: IItem,
230
+ prohibitedList?: string[]
231
+ ): ValidationInfo
232
+ ```
233
+
234
+ **Parameters:**
235
+ - `item` (`IItem`, required): The ArcGIS Online item whose title needs validation.
236
+ - `prohibitedList` (`string[]`, optional): A list of prohibited words or strings. Defaults to `PROHIBITED_LIST`.
237
+
238
+ **Returns:**
239
+ - `ValidationInfo`: An object containing the validation results for the title.
240
+
241
+ **Example:**
242
+ ```ts
243
+ import { isValidTitle } from '@vannizhang/living-atlas-content-validator';
244
+
245
+ const item = {
246
+ title: 'Mock Item Title',
247
+ culture: 'en',
248
+ // Other properties...
249
+ };
250
+
251
+ const prohibitedList = ['test', 'demo', 'eval'];
252
+
253
+ const validationInfo = isValidTitle(item, prohibitedList);
254
+ console.log(validationInfo);
255
+ ```
256
+
257
+ ---
258
+
259
+ ### `isValidAccessInformation`
260
+ Validates an item's "Credits (Attribution)" field, which provides information on the source of the item and its copyright status.
261
+
262
+ ```ts
263
+ import { isValidAccessInformation } from '@vannizhang/living-atlas-content-validator';
264
+
265
+ isValidAccessInformation(
266
+ item: IItem
267
+ ): ValidationInfo
268
+ ```
269
+
270
+ **Parameters:**
271
+ - `item` (`IItem`, required): The ArcGIS Online item whose "Credits (Attribution)" field needs validation.
272
+
273
+ **Returns:**
274
+ - `ValidationInfo`: An object containing the validation results for the "Credits (Attribution)" field.
275
+
276
+ **Example:**
277
+ ```ts
278
+ import { isValidAccessInformation } from '@vannizhang/living-atlas-content-validator';
279
+
280
+ const item = {
281
+ accessInformation: 'National Oceanic and Atmospheric Administration (NOAA)',
282
+ // Other properties...
283
+ };
284
+
285
+ const validationInfo = isValidAccessInformation(item);
286
+ console.log(validationInfo);
287
+ ```
288
+
289
+ ---
290
+
291
+ ### `isValidDescription`
292
+ Validates an item's description field.
293
+
294
+ ```ts
295
+ import { isValidDescription } from '@vannizhang/living-atlas-content-validator';
296
+
297
+ isValidDescription(
298
+ item: IItem
299
+ ): ValidationInfo
300
+ ```
301
+
302
+ **Parameters:**
303
+ - `item` (`IItem`, required): The ArcGIS Online item whose description field needs validation.
304
+
305
+ **Returns:**
306
+ - `ValidationInfo`: An object containing the validation results for the description field.
307
+
308
+ **Example:**
309
+ ```ts
310
+ import { isValidDescription } from '@vannizhang/living-atlas-content-validator';
311
+
312
+ const item = {
313
+ description: 'This is a detailed description of the item. It provides comprehensive information about the data, its sources, and how to use it effectively.',
314
+ // Other properties...
315
+ };
316
+
317
+ const validationInfo = isValidDescription(item);
318
+ console.log(validationInfo);
319
+ ```
320
+ ---
321
+
322
+ ### `isValidLicenseInfo`
323
+ Validates an item's "Terms of Use (license info)" field.
324
+
325
+ ```ts
326
+ import { isValidLicenseInfo } from '@vannizhang/living-atlas-content-validator';
327
+
328
+ isValidLicenseInfo(
329
+ item: IItem
330
+ ): ValidationInfo
331
+ ```
332
+
333
+ **Parameters:**
334
+ - `item` (`IItem`, required): The ArcGIS Online item whose "Terms of Use (license info)" field needs validation.
335
+
336
+ **Returns:**
337
+ - `ValidationInfo`: An object containing the validation results for the "Terms of Use (license info)" field.
338
+
339
+ **Example:**
340
+ ```ts
341
+ import { isValidLicenseInfo } from '@vannizhang/living-atlas-content-validator';
342
+
343
+ const item = {
344
+ licenseInfo: 'This data is licensed under the Open Data Commons Open Database License (ODbL). For more information, visit <a href="https://opendatacommons.org/licenses/odbl/">ODbL License</a>.',
345
+ // Other properties...
346
+ };
347
+
348
+ const validationInfo = isValidLicenseInfo(item);
349
+ console.log(validationInfo);
350
+ ```
351
+
352
+ ---
353
+
354
+ ### `isValidAccess`
355
+ Validates an item's sharing level to ensure it meets Living Atlas requirements.
356
+
357
+ ```ts
358
+ import { isValidAccess } from '@vannizhang/living-atlas-content-validator';
359
+
360
+ isValidAccess(
361
+ item: IItem
362
+ ): ValidationInfo
363
+ ```
364
+
365
+ **Parameters:**
366
+ - `item` (`IItem`, required): The ArcGIS Online item whose sharing level needs validation.
367
+
368
+ **Returns:**
369
+ - `ValidationInfo`: An object containing the validation results for the sharing level.
370
+
371
+ **Example:**
372
+ ```ts
373
+ import { isValidAccess } from '@vannizhang/living-atlas-content-validator';
374
+
375
+ const item = {
376
+ access: 'public', // Sharing level of the item
377
+ // Other properties...
378
+ };
379
+
380
+ const validationInfo = isValidAccess(item);
381
+ console.log(validationInfo);
382
+ ```
383
+
384
+ ---
385
+
386
+ ### `isValidSummary`
387
+ Validates an item's summary (snippet) field.
388
+
389
+ ```ts
390
+ import { isValidSummary } from '@vannizhang/living-atlas-content-validator';
391
+
392
+ isValidSummary(
393
+ item: IItem,
394
+ prohibitedList?: string[]
395
+ ): ValidationInfo
396
+ ```
397
+
398
+ **Parameters:**
399
+ - `item` (`IItem`, required): The ArcGIS Online item whose summary (snippet) field needs validation.
400
+ - `prohibitedList` (`string[]`, optional): A list of prohibited words or strings. Defaults to `PROHIBITED_LIST`.
401
+
402
+ **Returns:**
403
+ - `ValidationInfo`: An object containing the validation results for the summary field.
404
+
405
+ **Example:**
406
+ ```ts
407
+ import { isValidSummary } from '@vannizhang/living-atlas-content-validator';
408
+
409
+ const item = {
410
+ snippet: 'This is a brief summary of the item, providing key details and context for users.',
411
+ culture: 'en',
412
+ // Other properties...
413
+ };
414
+
415
+ const prohibitedList = ['test', 'demo', 'eval'];
416
+
417
+ const validationInfo = isValidSummary(item, prohibitedList);
418
+ console.log(validationInfo);
419
+ ```
420
+
421
+ ---
422
+
423
+ ### `isValidTags`
424
+ Validates an item's tags to ensure they meet ArcGIS Online and Living Atlas-specific rules.
425
+
426
+ ```ts
427
+ import { isValidTags } from '@vannizhang/living-atlas-content-validator';
428
+
429
+ isValidTags(
430
+ item: IItem,
431
+ prohibitedList?: string[]
432
+ ): ValidationInfo
433
+ ```
434
+
435
+ **Parameters:**
436
+ - `item` (`IItem`, required): The ArcGIS Online item whose tags need validation.
437
+ - `prohibitedList` (`string[]`, optional): A list of prohibited tags. Defaults to `PROHIBITED_LIST`.
438
+
439
+ **Returns:**
440
+ - `ValidationInfo`: An object containing the validation results for the tags.
441
+
442
+ **Example:**
443
+ ```ts
444
+ import { isValidTags } from '@vannizhang/living-atlas-content-validator';
445
+
446
+ const item = {
447
+ tags: ['climate', 'renewable energy', 'NOAA'],
448
+ // Other properties...
449
+ };
450
+
451
+ const prohibitedList = ['test', 'demo', 'eval'];
452
+
453
+ const validationInfo = isValidTags(item, prohibitedList);
454
+ console.log(validationInfo);
455
+ ```
456
+
457
+ ---
458
+
459
+ ### `isValidThumbnail`
460
+ Validates an item's thumbnail to ensure it meets Living Atlas-specific rules.
461
+
462
+ ```ts
463
+ import { isValidThumbnail } from '@vannizhang/living-atlas-content-validator';
464
+
465
+ isValidThumbnail(
466
+ item: IItem,
467
+ thumbnailDimension?: { width: number; height: number }
468
+ ): ValidationInfo
469
+ ```
470
+
471
+ **Parameters:**
472
+ - `item` (`IItem`, required): The ArcGIS Online item whose thumbnail needs validation.
473
+ - `thumbnailDimension` (`{ width: number; height: number }`, optional): The dimensions of the item's thumbnail.
474
+
475
+ **Returns:**
476
+ - `ValidationInfo`: An object containing the validation results for the thumbnail.
477
+
478
+ **Example:**
479
+ ```ts
480
+ import { isValidThumbnail } from '@vannizhang/living-atlas-content-validator';
481
+
482
+ const item = {
483
+ thumbnail: 'custom-thumbnail.png',
484
+ // Other properties...
485
+ };
486
+
487
+ const thumbnailDimension = { width: 610, height: 405 };
488
+
489
+ const validationInfo = isValidThumbnail(item, thumbnailDimension);
490
+ console.log(validationInfo);
491
+ ```
492
+
493
+ ---
494
+
495
+ ### `isDeprecated`
496
+ Validates an item's `contentStatus` to ensure it is not marked as **deprecated**.
497
+
498
+ ```ts
499
+ import { isDeprecated } from '@vannizhang/living-atlas-content-validator';
500
+
501
+ isDeprecated(
502
+ item: IItem
503
+ ): ValidationInfo
504
+ ```
505
+
506
+ **Parameters:**
507
+ - `item` (`IItem`, required): The ArcGIS Online item whose `contentStatus` needs validation.
508
+
509
+ **Returns:**
510
+ - `ValidationInfo`: An object containing the validation results for the `contentStatus`.
511
+
512
+ **Example:**
513
+ ```ts
514
+ import { isDeprecated } from '@vannizhang/living-atlas-content-validator';
515
+
516
+ const item = {
517
+ contentStatus: 'deprecated', // Content status of the item
518
+ // Other properties...
519
+ };
520
+
521
+ const validationInfo = isDeprecated(item);
522
+ console.log(validationInfo);
523
+ ```
524
+
525
+ ---
526
+
527
+ ### `isDeleteProtectionEnabled`
528
+ Validates an item's `protected` property to ensure **Delete Protection** is enabled.
529
+
530
+ ```ts
531
+ import { isDeleteProtectionEnabled } from '@vannizhang/living-atlas-content-validator';
532
+
533
+ isDeleteProtectionEnabled(
534
+ item: IItem
535
+ ): ValidationInfo
536
+ ```
537
+
538
+ **Parameters:**
539
+ - `item` (`IItem`, required): The ArcGIS Online item whose `protected` property needs validation.
540
+
541
+ **Returns:**
542
+ - `ValidationInfo`: An object containing the validation results for the `protected` property.
543
+
544
+ **Remark:**
545
+ - The delete protection status is **only exposed** to the item owner. The Living Atlas team has been using a workaround to determine the delete protection status for items owned by other users.
546
+
547
+ **Example:**
548
+ ```ts
549
+ import { isDeleteProtectionEnabled } from '@vannizhang/living-atlas-content-validator';
550
+
551
+ const item = {
552
+ protected: true, // Indicates whether Delete Protection is enabled
553
+ // Other properties...
554
+ };
555
+
556
+ const validationInfo = isDeleteProtectionEnabled(item);
557
+ console.log(validationInfo);
558
+ ```
559
+
560
+ ---
561
+
562
+ ### `isValidUserProfileName`
563
+ Validates an item owner's profile name to ensure it meets Living Atlas-specific rules.
564
+
565
+ ```ts
566
+ import { isValidUserProfileName } from '@vannizhang/living-atlas-content-validator';
567
+
568
+ isValidUserProfileName(
569
+ userProfile: IUser
570
+ ): ValidationInfo
571
+ ```
572
+
573
+ **Parameters:**
574
+ - `userProfile` (`IUser`, required): The user profile of the item's owner.
575
+
576
+ **Returns:**
577
+ - `ValidationInfo`: An object containing the validation results for the user profile name.
578
+
579
+ **Example:**
580
+ ```ts
581
+ import { isValidUserProfileName } from '@vannizhang/living-atlas-content-validator';
582
+
583
+ const userProfile = {
584
+ fullName: 'John_Doe',
585
+ culture: 'en',
586
+ // Other properties...
587
+ };
588
+
589
+ const validationInfo = isValidUserProfileName(userProfile);
590
+ console.log(validationInfo);
591
+ ```
592
+
593
+ ---
594
+
595
+ ### `isValidUserProfileDescription`
596
+ Validates an item owner's profile description to ensure it meets Living Atlas-specific rules.
597
+
598
+ ```ts
599
+ import { isValidUserProfileDescription } from '@vannizhang/living-atlas-content-validator';
600
+
601
+ isValidUserProfileDescription(
602
+ userProfile: IUser
603
+ ): ValidationInfo
604
+ ```
605
+
606
+ **Parameters:**
607
+ - `userProfile` (`IUser`, required): The user profile of the item's owner.
608
+
609
+ **Returns:**
610
+ - `ValidationInfo`: An object containing the validation results for the user profile description.
611
+
612
+ **Example:**
613
+ ```ts
614
+ import { isValidUserProfileDescription } from '@vannizhang/living-atlas-content-validator';
615
+
616
+ const userProfile = {
617
+ description: 'I am a GIS professional with expertise in mapping and spatial analysis. Contact me at john.doe@example.com. Visit my portfolio at https://johndoe.com.',
618
+ culture: 'en',
619
+ // Other properties...
620
+ };
621
+
622
+ const validationInfo = isValidUserProfileDescription(userProfile);
623
+ console.log(validationInfo);
624
+ ```
625
+
626
+ ---
627
+
628
+ ### `isValidUserProfileThumbnail`
629
+ Validates a user's profile thumbnail to ensure it meets Living Atlas-specific rules.
630
+
631
+ ```ts
632
+ import { isValidUserProfileThumbnail } from '@vannizhang/living-atlas-content-validator';
633
+
634
+ isValidUserProfileThumbnail(
635
+ userProfile: IUser
636
+ ): ValidationInfo
637
+ ```
638
+
639
+ **Parameters:**
640
+ - `userProfile` (`IUser`, required): The user profile of the item's owner.
641
+
642
+ **Returns:**
643
+ - `ValidationInfo`: An object containing the validation results for the user profile thumbnail.
644
+
645
+ **Example:**
646
+ ```ts
647
+ import { isValidUserProfileThumbnail } from '@vannizhang/living-atlas-content-validator';
648
+
649
+ const userProfile = {
650
+ thumbnail: 'custom-thumbnail.png',
651
+ // Other properties...
652
+ };
653
+
654
+ const validationInfo = isValidUserProfileThumbnail(userProfile);
655
+ console.log(validationInfo);
656
+ ```
657
+
658
+ ---
659
+
660
+ ### `checkTitleAndSnippetSearchability`
661
+ Checks for required and recommended text in an item's title and summary (snippet) to ensure they are search-friendly.
662
+
663
+ ```ts
664
+ import { checkTitleAndSnippetSearchability } from '@vannizhang/living-atlas-content-validator';
665
+
666
+ checkTitleAndSnippetSearchability(
667
+ item: IItem,
668
+ options?: {
669
+ customPatternsForLocationInfo?: string[];
670
+ customPatternsForDataVintageInfo?: string[];
671
+ customPatternsForSourceInfo?: string[];
672
+ customPatternsForTopicInfo?: string[];
46
673
  }
47
- );
674
+ ): ValidationInfo
48
675
  ```
49
676
 
50
- Here is an example of output returned by `validate`:
51
- ```js
52
- {
53
- "id": "12345",
54
- "totalScore": 60,
55
- "validatedItem": {
56
- "access": {
57
- "property": "access",
58
- "label": "Must be public",
59
- "maxScore": 9,
60
- "score": 2,
61
- "messages": [
62
- {
63
- "code": "",
64
- "message": "Must be public"
65
- }
66
- ],
67
- "weight": 4,
68
- "critical": true
69
- },
70
- "accessInformation": {
71
- "property": "accessInformation",
72
- "label": "Add credits",
73
- "maxScore": 8,
74
- "score": 0,
75
- "messages": [
76
- {
77
- "code": "",
78
- "message": "Add credits"
79
- }
80
- ],
81
- "weight": 7,
82
- "critical": false
83
- },
84
- "description": {
85
- "property": "description",
86
- "label": "Improve description",
87
- "maxScore": 8,
88
- "score": 1,
89
- "messages": [
90
- {
91
- "code": "",
92
- "message": "Description has no links"
93
- },
94
- {
95
- "code": "",
96
- "message": "Description too short"
97
- }
98
- ],
99
- "weight": 3,
100
- "critical": true
101
- },
102
- "layerCount": {
103
- "property": "layers",
104
- "label": "Reduce the number of layers",
105
- //...
106
- },
107
- "licenseInfo": {
108
- "property": "licenseInfo",
109
- "label": "Improve access and use constraints",
110
- //...
111
- },
112
- "snippet": {
113
- "property": "snippet",
114
- "label": "Improve summary",
115
- //...
116
- },
117
- "ssl": {
118
- "property": "ssl",
119
- "label": "Use HTTPS in the URL",
120
- //...
121
- },
122
- "tags": {
123
- "property": "tags",
124
- "label": "Improve tags",
125
- //...
126
- },
127
- "thumbnail": {
128
- "property": "thumbnail",
129
- "label": "Improve thumbnail",
130
- //...
131
- },
132
- "title": {
133
- "property": "title",
134
- "label": "Improve title",
135
- //...
136
- }
137
- },
138
- "validatedProfile": {
139
- "userProfileDescription": {
140
- "property": "userProfileDescription",
141
- "label": "Improve profile description",
142
- "maxScore": 7,
143
- "score": 1,
144
- "messages": [
145
- {
146
- "code": "",
147
- "message": "Profile description does not contain an email"
148
- },
149
- {
150
- "code": "",
151
- "message": "Profile description does not contain a link"
152
- },
153
- //...
154
- ],
155
- "weight": 12,
156
- "critical": true
157
- },
158
- "userProfileFullName": {
159
- "property": "userProfileName",
160
- "label": "Improve profile full name",
161
- //...
162
- },
163
- "userProfileThumbnail": {
164
- "property": "userProfileThumbnail",
165
- "label": "Improve profile thumbnail",
166
- //...
167
- }
168
- },
169
- }
677
+ **Parameters:**
678
+ - `item` (`IItem`, required): The ArcGIS Online item whose title and snippet need validation.
679
+ - `options` (optional): Custom patterns for matching specific information.
680
+ - `customPatternsForLocationInfo` (`string[]`): Custom patterns for location information.
681
+ - `customPatternsForDataVintageInfo` (`string[]`): Custom patterns for data vintage information.
682
+ - `customPatternsForSourceInfo` (`string[]`): Custom patterns for source information.
683
+ - `customPatternsForTopicInfo` (`string[]`): Custom patterns for topic information.
684
+
685
+ **Returns:**
686
+ - `ValidationInfo`: An object containing the validation results for the title and snippet.
687
+
688
+ **Example:**
689
+ ```ts
690
+ import { checkTitleAndSnippetSearchability } from '@vannizhang/living-atlas-content-validator';
691
+
692
+ const item = {
693
+ title: 'Global Earthquake Data 2023',
694
+ snippet: 'Earthquake data from NOAA for the year 2023.',
695
+ // Other properties...
696
+ };
697
+
698
+ const options = {
699
+ customPatternsForLocationInfo: ['Global', 'New York'],
700
+ customPatternsForDataVintageInfo: ['2023', 'Monthly'],
701
+ customPatternsForSourceInfo: ['NOAA', 'Esri'],
702
+ customPatternsForTopicInfo: ['Earthquakes', 'Public Health Dashboard'],
703
+ };
704
+
705
+ const validationInfo = checkTitleAndSnippetSearchability(item, options);
706
+ console.log(validationInfo);
170
707
  ```
171
708
 
172
- ## Configuration
173
- You can set the language to be used in the output validation messages with the `setStrings` function. Here is an example:
174
- ```js
175
- import { setStrings } from `@vannizhang/living-atlas-content-validator`
709
+ ---
176
710
 
177
- // You can choose any of these six languages: 'en', 'de', 'es', 'fr', 'ja', 'pt-br'
178
- setStrings('de'); // use German
711
+ ### `isEligibleForCheckingTitleAndSnippetSearchability`
712
+ Determines if an item is eligible for checking title and snippet searchability.
713
+
714
+ ```ts
715
+ import { isEligibleForCheckingTitleAndSnippetSearchability } from '@vannizhang/living-atlas-content-validator';
716
+
717
+ isEligibleForCheckingTitleAndSnippetSearchability(
718
+ item: IItem
719
+ ): boolean
179
720
  ```
180
721
 
181
- ### License
182
- Copyright &copy; 2022 Esri
722
+ **Parameters:**
723
+ - `item` (`IItem`, required): The ArcGIS Online item to check.
724
+
725
+ **Returns:**
726
+ - `boolean`: `true` if the item meets the criteria for checking title and snippet searchability, otherwise `false`.
727
+
728
+ **Eligibility Criteria:**
729
+ 1. The item is a layer.
730
+ 2. The item is English-based.
731
+
732
+ **Remarks:**
733
+ - The locale is determined by both the item's `culture` property and the item's owner.
734
+
735
+ **Example:**
736
+ ```ts
737
+ import { isEligibleForCheckingTitleAndSnippetSearchability } from '@vannizhang/living-atlas-content-validator';
738
+
739
+ const item = {
740
+ id: 'mock-item-id',
741
+ owner: 'mock-owner',
742
+ title: 'Mock Item Title',
743
+ culture: 'en',
744
+ type: 'Feature Layer',
745
+ // Other properties...
746
+ };
747
+
748
+ const isEligible = isEligibleForCheckingTitleAndSnippetSearchability(item);
749
+ console.log(isEligible); // true or false
750
+ ```
751
+
752
+ ---
753
+
754
+ ### `matchLocationInfo`
755
+ Matches location information from an item's title and snippet using predefined or custom matching patterns.
756
+
757
+ ```ts
758
+ import { matchLocationInfo } from '@vannizhang/living-atlas-content-validator';
759
+
760
+ matchLocationInfo(
761
+ item: IItem,
762
+ customMatchingPatterns?: string[]
763
+ ): MatchResult[]
764
+ ```
765
+
766
+ **Parameters:**
767
+ - `item` (`IItem`, required): The ArcGIS Online item containing the title and snippet to search for location information.
768
+ - `customMatchingPatterns` (`string[]`, optional): Custom matching patterns to include in the search.
769
+
770
+ **Returns:**
771
+ - `MatchResult[]`: An array of matched results for location information after deduplication and removing overlaps.
772
+
773
+ **Example:**
774
+ ```ts
775
+ import { matchLocationInfo } from '@vannizhang/living-atlas-content-validator';
776
+
777
+ const item = {
778
+ title: 'Earthquake Data for California',
779
+ snippet: 'This dataset provides earthquake information for the state of California.',
780
+ // Other properties...
781
+ };
782
+
783
+ const customPatterns = ['California', 'Los Angeles'];
784
+
785
+ const matchedLocations = matchLocationInfo(item, customPatterns);
786
+ console.log(matchedLocations);
787
+ ```
788
+
789
+ ---
790
+
791
+ ### `isRecognizedLocation`
792
+ Determines if a given string is recognized as location information.
793
+
794
+ ```ts
795
+ import { isRecognizedLocation } from '@vannizhang/living-atlas-content-validator';
796
+
797
+ isRecognizedLocation(
798
+ str: string
799
+ ): boolean
800
+ ```
801
+
802
+ **Parameters:**
803
+ - `str` (`string`, required): The string to check.
804
+
805
+ **Returns:**
806
+ - `boolean`: `true` if the string is recognized as location information, `false` otherwise.
807
+
808
+ **Example:**
809
+ ```ts
810
+ import { isRecognizedLocation } from '@vannizhang/living-atlas-content-validator';
811
+
812
+ const location = 'California';
813
+
814
+ const isRecognized = isRecognizedLocation(location);
815
+ console.log(isRecognized); // true or false
816
+ ```
817
+
818
+ ---
819
+
820
+ ### `isRejectedLocationInfo`
821
+ Determines if a given string is rejected as location information.
822
+
823
+ ```ts
824
+ import { isRejectedLocationInfo } from '@vannizhang/living-atlas-content-validator';
825
+
826
+ isRejectedLocationInfo(
827
+ str: string
828
+ ): boolean
829
+ ```
830
+
831
+ **Parameters:**
832
+ - `str` (`string`, required): The string to check.
833
+
834
+ **Returns:**
835
+ - `boolean`: `true` if the string is rejected as location information, `false` otherwise.
836
+
837
+ **Example:**
838
+ ```ts
839
+ import { isRejectedLocationInfo } from '@vannizhang/living-atlas-content-validator';
840
+
841
+ const location = 'Unknown Location';
842
+
843
+ const isRejected = isRejectedLocationInfo(location);
844
+ console.log(isRejected); // true or false
845
+ ```
846
+
847
+ ---
848
+
849
+ ### `matchSourceInfo`
850
+ Matches source information from an item's title and snippet using predefined or custom matching patterns.
851
+
852
+ ```ts
853
+ import { matchSourceInfo } from '@vannizhang/living-atlas-content-validator';
854
+
855
+ matchSourceInfo(
856
+ item: IItem,
857
+ customMatchingPatterns?: string[]
858
+ ): MatchResult[]
859
+ ```
860
+
861
+ **Parameters:**
862
+ - `item` (`IItem`, required): The ArcGIS Online item containing the title and snippet to search for source information.
863
+ - `customMatchingPatterns` (`string[]`, optional): Custom matching patterns to include in the search.
864
+
865
+ **Returns:**
866
+ - `MatchResult[]`: An array of matched results for source information after deduplication and removing overlaps.
867
+
868
+ **Example:**
869
+ ```ts
870
+ import { matchSourceInfo } from '@vannizhang/living-atlas-content-validator';
871
+
872
+ const item = {
873
+ title: 'Earthquake Data from NOAA',
874
+ snippet: 'This dataset provides earthquake information sourced from NOAA.',
875
+ // Other properties...
876
+ };
877
+
878
+ const customPatterns = ['NOAA', 'USGS'];
879
+
880
+ const matchedSources = matchSourceInfo(item, customPatterns);
881
+ console.log(matchedSources);
882
+ ```
883
+
884
+ ---
885
+
886
+ ### `isRecognizedSource`
887
+ Determines if a given string is recognized as source information.
888
+
889
+ ```ts
890
+ import { isRecognizedSource } from '@vannizhang/living-atlas-content-validator';
891
+
892
+ isRecognizedSource(
893
+ str: string
894
+ ): boolean
895
+ ```
896
+
897
+ **Parameters:**
898
+ - `str` (`string`, required): The string to check.
899
+
900
+ **Returns:**
901
+ - `boolean`: `true` if the string is recognized as source information, `false` otherwise.
902
+
903
+ **Example:**
904
+ ```ts
905
+ import { isRecognizedSource } from '@vannizhang/living-atlas-content-validator';
906
+
907
+ const source = 'NOAA';
908
+
909
+ const isRecognized = isRecognizedSource(source);
910
+ console.log(isRecognized); // true or false
911
+ ```
912
+
913
+ ---
914
+
915
+ ### `isRejectedSourceInfo`
916
+ Determines if a given string is rejected as source information.
917
+
918
+ ```ts
919
+ import { isRejectedSourceInfo } from '@vannizhang/living-atlas-content-validator';
920
+
921
+ isRejectedSourceInfo(
922
+ str: string
923
+ ): boolean
924
+ ```
925
+
926
+ **Parameters:**
927
+ - `str` (`string`, required): The string to check.
928
+
929
+ **Returns:**
930
+ - `boolean`: `true` if the string is rejected as source information, `false` otherwise.
931
+
932
+ **Example:**
933
+ ```ts
934
+ import { isRejectedSourceInfo } from '@vannizhang/living-atlas-content-validator';
935
+
936
+ const source = 'Unknown Source';
937
+
938
+ const isRejected = isRejectedSourceInfo(source);
939
+ console.log(isRejected); // true or false
940
+ ```
941
+
942
+ ---
943
+
944
+ ### `matchTopicInfo`
945
+ Matches topic information from an item's title and snippet using predefined or custom matching patterns.
946
+
947
+ ```ts
948
+ import { matchTopicInfo } from '@vannizhang/living-atlas-content-validator';
949
+
950
+ matchTopicInfo(
951
+ item: IItem,
952
+ customMatchingPatterns?: string[]
953
+ ): MatchResult[]
954
+ ```
955
+
956
+ **Parameters:**
957
+ - `item` (`IItem`, required): The ArcGIS Online item containing the title and snippet to search for topic information.
958
+ - `customMatchingPatterns` (`string[]`, optional): Custom matching patterns to include in the search.
959
+
960
+ **Returns:**
961
+ - `MatchResult[]`: An array of matched results for topic information after deduplication and removing overlaps.
962
+
963
+ **Example:**
964
+ ```ts
965
+ import { matchTopicInfo } from '@vannizhang/living-atlas-content-validator';
966
+
967
+ const item = {
968
+ title: 'Climate Change Impact Analysis',
969
+ snippet: 'This dataset provides insights into the impact of climate change on global ecosystems.',
970
+ // Other properties...
971
+ };
972
+
973
+ const customPatterns = ['Climate Change', 'Global Warming'];
974
+
975
+ const matchedTopics = matchTopicInfo(item, customPatterns);
976
+ console.log(matchedTopics);
977
+ ```
978
+
979
+ ---
980
+
981
+ ### `isRecognizedTopic`
982
+ Determines if a given string is recognized as topic information.
983
+
984
+ ```ts
985
+ import { isRecognizedTopic } from '@vannizhang/living-atlas-content-validator';
986
+
987
+ isRecognizedTopic(
988
+ str: string
989
+ ): boolean
990
+ ```
991
+
992
+ **Parameters:**
993
+ - `str` (`string`, required): The string to check.
994
+
995
+ **Returns:**
996
+ - `boolean`: `true` if the string is recognized as topic information, `false` otherwise.
997
+
998
+ **Example:**
999
+ ```ts
1000
+ import { isRecognizedTopic } from '@vannizhang/living-atlas-content-validator';
1001
+
1002
+ const topic = 'Climate Change';
1003
+
1004
+ const isRecognized = isRecognizedTopic(topic);
1005
+ console.log(isRecognized); // true or false
1006
+ ```
1007
+
1008
+ ---
1009
+
1010
+ ### `isRejectedTopicInfo`
1011
+ Determines if a given string is rejected as topic information.
1012
+
1013
+ ```ts
1014
+ import { isRejectedTopicInfo } from '@vannizhang/living-atlas-content-validator';
1015
+
1016
+ isRejectedTopicInfo(
1017
+ str: string
1018
+ ): boolean
1019
+ ```
1020
+
1021
+ **Parameters:**
1022
+ - `str` (`string`, required): The string to check.
1023
+
1024
+ **Returns:**
1025
+ - `boolean`: `true` if the string is rejected as topic information, `false` otherwise.
1026
+
1027
+ **Example:**
1028
+ ```ts
1029
+ import { isRejectedTopicInfo } from '@vannizhang/living-atlas-content-validator';
1030
+
1031
+ const topic = 'Unknown Topic';
1032
+
1033
+ const isRejected = isRejectedTopicInfo(topic);
1034
+ console.log(isRejected); // true or false
1035
+ ```
1036
+
1037
+ ---
1038
+
1039
+ ### `matchDateTimeInfo`
1040
+ Matches date and time information from an item's title and snippet using predefined or custom matching patterns.
1041
+
1042
+ ```ts
1043
+ import { matchDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1044
+
1045
+ matchDateTimeInfo(
1046
+ item: IItem,
1047
+ customMatchingPatterns?: string[]
1048
+ ): MatchResult[]
1049
+ ```
1050
+
1051
+ **Parameters:**
1052
+ - `item` (`IItem`, required): The ArcGIS Online item containing the title and snippet to search for date and time information.
1053
+ - `customMatchingPatterns` (`string[]`, optional): Custom matching patterns to include in the search.
1054
+
1055
+ **Returns:**
1056
+ - `MatchResult[]`: An array of matched results for date and time information after deduplication and removing overlaps.
1057
+
1058
+ **Example:**
1059
+ ```ts
1060
+ import { matchDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1061
+
1062
+ const item = {
1063
+ title: 'Climate Data for 2020-2025',
1064
+ snippet: 'This dataset provides monthly climate data for the years 2020 to 2025.',
1065
+ // Other properties...
1066
+ };
1067
+
1068
+ const customPatterns = ['2020', '2025'];
1069
+
1070
+ const matchedDateTimeInfo = matchDateTimeInfo(item, customPatterns);
1071
+ console.log(matchedDateTimeInfo);
1072
+ ```
1073
+
1074
+ ---
1075
+
1076
+ ### `isRecognizedDateTimeInfo`
1077
+ Determines if a given string is recognized as date and time information.
1078
+
1079
+ ```ts
1080
+ import { isRecognizedDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1081
+
1082
+ isRecognizedDateTimeInfo(
1083
+ str: string
1084
+ ): boolean
1085
+ ```
1086
+
1087
+ **Parameters:**
1088
+ - `str` (`string`, required): The string to check.
1089
+
1090
+ **Returns:**
1091
+ - `boolean`: `true` if the string is recognized as date and time information, `false` otherwise.
1092
+
1093
+ **Example:**
1094
+ ```ts
1095
+ import { isRecognizedDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1096
+
1097
+ const dateTimeInfo = '2020-2025';
1098
+
1099
+ const isRecognized = isRecognizedDateTimeInfo(dateTimeInfo);
1100
+ console.log(isRecognized); // true or false
1101
+ ```
1102
+
1103
+ ---
1104
+
1105
+ ### `isRejectedDateTimeInfo`
1106
+ Determines if a given string is rejected as date and time information.
1107
+
1108
+ ```ts
1109
+ import { isRejectedDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1110
+
1111
+ isRejectedDateTimeInfo(
1112
+ str: string
1113
+ ): boolean
1114
+ ```
1115
+
1116
+ **Parameters:**
1117
+ - `str` (`string`, required): The string to check.
1118
+
1119
+ **Returns:**
1120
+ - `boolean`: `true` if the string is rejected as date and time information, `false` otherwise.
1121
+
1122
+ **Example:**
1123
+ ```ts
1124
+ import { isRejectedDateTimeInfo } from '@vannizhang/living-atlas-content-validator';
1125
+
1126
+ const dateTimeInfo = 'Unknown Year';
1127
+
1128
+ const isRejected = isRejectedDateTimeInfo(dateTimeInfo);
1129
+ console.log(isRejected); // true or false
1130
+ ```
1131
+
1132
+ ---
1133
+
1134
+ ### `getLivingAtlasSupportedItemTypes`
1135
+ Returns an array of item types supported by Living Atlas.
1136
+
1137
+ ```ts
1138
+ import { getLivingAtlasSupportedItemTypes } from '@vannizhang/living-atlas-content-validator';
1139
+
1140
+ getLivingAtlasSupportedItemTypes(): LivingAtlasSupportedItemType[]
1141
+ ```
1142
+
1143
+ **Returns:**
1144
+ - `LivingAtlasSupportedItemType[]`: An array of Living Atlas supported item types.
1145
+
1146
+ **Description:**
1147
+ This function creates a new array containing all the predefined item types that are supported by Living Atlas from the configuration.
1148
+
1149
+ **Example:**
1150
+ ```ts
1151
+ import { getLivingAtlasSupportedItemTypes } from '@vannizhang/living-atlas-content-validator';
1152
+
1153
+ const supportedItemTypes = getLivingAtlasSupportedItemTypes();
1154
+ console.log(supportedItemTypes);
1155
+ ```
1156
+
1157
+ ---
1158
+
1159
+ ### `checkIsLivingAtlasSupportedItemType`
1160
+ Checks if a given item type is supported by Living Atlas.
1161
+
1162
+ ```ts
1163
+ import { checkIsLivingAtlasSupportedItemType } from '@vannizhang/living-atlas-content-validator';
1164
+
1165
+ checkIsLivingAtlasSupportedItemType(
1166
+ item: IItem
1167
+ ): boolean
1168
+ ```
1169
+
1170
+ **Parameters:**
1171
+ - `item` (`IItem`, required): The ArcGIS Online item to check.
1172
+
1173
+ **Returns:**
1174
+ - `boolean`: `true` if the item type is supported by Living Atlas, otherwise `false`.
1175
+
1176
+ **Description:**
1177
+ This function determines whether the provided item type string is included in the predefined list of item types supported by Living Atlas.
1178
+
1179
+ **Example:**
1180
+ ```ts
1181
+ import { checkIsLivingAtlasSupportedItemType } from '@vannizhang/living-atlas-content-validator';
1182
+
1183
+ const item = {
1184
+ id: 'mock-item-id',
1185
+ type: 'Web Map',
1186
+ // Other properties...
1187
+ };
1188
+
1189
+ const isSupported = checkIsLivingAtlasSupportedItemType(item);
1190
+ console.log(isSupported); // true or false
1191
+ ```
1192
+
1193
+ ---
1194
+
1195
+
1196
+
1197
+ ## Types
1198
+
1199
+ ### `ValidationResult`
1200
+ The `ValidationResult` type represents the outcome of the validation process, providing detailed assessments for both the ArcGIS Online item and its owner's profile. It helps determine whether an item meets the necessary criteria for nomination to the ArcGIS Living Atlas.
1201
+
1202
+ ```ts
1203
+ export type ValidationResult = {
1204
+ validatedItem: {
1205
+ /**
1206
+ * Validation result for the item's sharing level.
1207
+ */
1208
+ access: ValidationInfo;
1209
+
1210
+ /**
1211
+ * Validation result for the item's credits/attribution information.
1212
+ */
1213
+ accessInformation: ValidationInfo;
1214
+
1215
+ /**
1216
+ * Validation result for the item's description text.
1217
+ */
1218
+ description: ValidationInfo;
1219
+
1220
+ /**
1221
+ * Validation result for the item's license information.
1222
+ */
1223
+ licenseInfo: ValidationInfo;
1224
+
1225
+ /**
1226
+ * Validation result for the item's snippet (short summary text).
1227
+ */
1228
+ snippet: ValidationInfo;
1229
+
1230
+ /**
1231
+ * Validation result for the item's SSL configuration, ensuring HTTPS support.
1232
+ */
1233
+ ssl: ValidationInfo;
1234
+
1235
+ /**
1236
+ * Validation result for the item's tags.
1237
+ */
1238
+ tags: ValidationInfo;
1239
+
1240
+ /**
1241
+ * Validation result for the item's thumbnail image.
1242
+ */
1243
+ thumbnail: ValidationInfo;
1244
+
1245
+ /**
1246
+ * Validation result for the item's title.
1247
+ */
1248
+ title: ValidationInfo;
1249
+
1250
+ /**
1251
+ * Validation result for the item's content status, checking for deprecated content.
1252
+ */
1253
+ deprecated: ValidationInfo;
1254
+
1255
+ /**
1256
+ * Validation result for the item's "delete protection" property.
1257
+ */
1258
+ deleteProtection: ValidationInfo;
1259
+
1260
+ /**
1261
+ * Validation result for ensuring recommended text is included in the item's title and summary.
1262
+ */
1263
+ recommendedTextInTitleAndSummary: ValidationInfo;
1264
+ };
1265
+ validatedProfile: {
1266
+ /**
1267
+ * Validation result for the item owner's profile description.
1268
+ */
1269
+ userProfileDescription: ValidationInfo;
1270
+
1271
+ /**
1272
+ * Validation result for the item owner's full name.
1273
+ */
1274
+ userProfileFullName: ValidationInfo;
1275
+
1276
+ /**
1277
+ * Validation result for the item owner's profile thumbnail image.
1278
+ */
1279
+ userProfileThumbnail: ValidationInfo;
1280
+ };
1281
+ /**
1282
+ * Id of the ArcGIS Online Item
1283
+ */
1284
+ id: string;
1285
+ /**
1286
+ * total score of the validation result
1287
+ */
1288
+ totalScore: number;
1289
+ /**
1290
+ * Indicate if the item can be nominated to Living Atlas based on the validation results.
1291
+ * This property is determined based on the following criteria:
1292
+ *
1293
+ * - the total score of the validation result is greater than or equal to the minimum score required for nomination (default is 80%).
1294
+ * - It is shared with the public.
1295
+ * - Its thumbnail image meets the required dimension.
1296
+ * - It has a snippet text.
1297
+ * - It has a description text.
1298
+ * - The item owner has a user profile description.
1299
+ */
1300
+ canBeNominated: boolean;
1301
+ };
1302
+ ```
1303
+ ---
1304
+
1305
+ ### `ValidationResultStatus`
1306
+ Represents the status of a validation result for a specific rule. This type indicates the outcome of the validation process for each rule and helps in understanding how well the item meets the criteria defined by the validation rules.
1307
+
1308
+ - `pass`: The item meets the criteria for this validation rule.
1309
+ - `warning`: The item meets the criteria but there are some suggestions for improvement or potential issues to address.
1310
+ - `error`: The item does not meet the criteria for this validation rule and requires correction.
1311
+ - `not-applicable`: Indicates that the validation rule is not applicable to the item being validated. This can happen if the rule does not apply to the type of item or if certain conditions are not met for the validation to be relevant.
1312
+ - `unknown`: This is the default status when a `ValidationInfo` object is created but the validation process has not yet been executed. It indicates that the validation status is yet to be determined.
1313
+
1314
+ ```ts
1315
+ export type ValidationResultStatus =
1316
+ | 'pass'
1317
+ | 'warning'
1318
+ | 'error'
1319
+ | 'not-applicable'
1320
+ | 'unknown';
1321
+ ```
1322
+
1323
+ ---
1324
+
1325
+ ### `ValidationInfo`
1326
+
1327
+ The `ValidationInfo` type provides detailed information about a specific validation rule, including its purpose, scoring criteria, and status.
1328
+
1329
+ ```ts
1330
+ export type ValidationInfo = {
1331
+ /**
1332
+ * The title string tells the user what this validation rule checks, e.g., "Check Thumbnail" or "Check Number of Layers".
1333
+ */
1334
+ title: string;
1335
+ /**
1336
+ * The label text will be used to instruct the user what they should do, e.g., "Improve Thumbnail" or "Reduce Number of Layers".
1337
+ */
1338
+ label: string;
1339
+ /**
1340
+ * Array of validation messages.
1341
+ */
1342
+ messages: ValidationMessage[];
1343
+ /**
1344
+ * Maximum score this validation rule can receive.
1345
+ */
1346
+ maxScore: number;
1347
+ /**
1348
+ * Final score that the item received for this validation rule.
1349
+ */
1350
+ score: number;
1351
+ /**
1352
+ * Weight assigned to this validation rule.
1353
+ */
1354
+ weight: number;
1355
+ /**
1356
+ * A factor ranging between 0 and 1 used to calculate the final score by multiplying it with the weight number.
1357
+ */
1358
+ weightFactor: number;
1359
+ /**
1360
+ * Status of the validation result.
1361
+ */
1362
+ status: ValidationResultStatus;
1363
+ /**
1364
+ * If true, this validation rule is a binary check, i.e., it can only pass or fail.
1365
+ */
1366
+ isBinaryCheck: boolean;
1367
+ };
1368
+ ```
1369
+
1370
+ ---
1371
+
1372
+ ### `MatchResult`
1373
+ Represents the result of a pattern match operation.
1374
+
1375
+ ```ts
1376
+ export type MatchResult = {
1377
+ /**
1378
+ * The string that was matched by the pattern.
1379
+ */
1380
+ matchedString: string;
1381
+ /**
1382
+ * The source of the pattern that was used for matching:
1383
+ * - 'predefined' - This indicates that the matched string was found using predefined patterns that are built into the validator.
1384
+ * - 'additional' - This indicates that the matched string was found using additional custom patterns loaded via configureSettings.
1385
+ * - 'custom' - This indicates that the matched string was found using custom patterns defined by the user.
1386
+ */
1387
+ patternSource: MatchPatternSource;
1388
+ };
1389
+ ```
1390
+
1391
+ ## Issues
1392
+ Find a bug or want to request a new feature? Please let us know by submitting an issue.
1393
+
1394
+ ## License
1395
+ Copyright &copy; 5 Esri
183
1396
 
184
1397
  Licensed under the Apache License, Version 2.0 (the "License");
185
1398
  you may not use this file except in compliance with the License.
@@ -193,4 +1406,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
193
1406
  See the License for the specific language governing permissions and
194
1407
  limitations under the License.
195
1408
 
196
- A copy of the license is available in the repository's [LICENSE](./LICENSE) file.
1409
+ A copy of the license is available in the repository's [LICENSE](./LICENSE) file.
1410
+ ````