@211la/search-client 0.3.3 → 0.3.7

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/dist/index.js CHANGED
@@ -75,16 +75,89 @@ function __spreadArray(to, from, pack) {
75
75
  var INDEX_NAME = 'instant_search';
76
76
  var DEFAULT_HITS_PER_PAGE = 20;
77
77
 
78
- var keyword = (function (keyword, fields) {
79
- return keyword
80
- ? {
81
- query_string: {
82
- query: keyword + "*",
83
- default_operator: 'AND',
84
- fields: fields,
85
- },
78
+ var splitPath = function (path) {
79
+ var idx = path.indexOf('.');
80
+ if (idx === -1) {
81
+ return [path];
82
+ }
83
+ return [path.slice(0, idx), path.slice(idx + 1)];
84
+ };
85
+ var deepSet = function (obj, path, value) {
86
+ var props = splitPath(path);
87
+ if (props.length === 1) {
88
+ obj[props[0]] = value;
89
+ return;
90
+ }
91
+ var prop = props[0], rest = props[1];
92
+ if (!obj[prop]) {
93
+ obj[prop] = {};
94
+ }
95
+ deepSet(obj[prop], rest, value);
96
+ };
97
+ var deepGet = function (obj, path) {
98
+ var props = splitPath(path);
99
+ if (props.length === 1) {
100
+ var value_1 = obj[props[0]];
101
+ if (typeof value_1 === 'undefined') {
102
+ return null;
86
103
  }
87
- : null;
104
+ return value_1;
105
+ }
106
+ var prop = props[0], rest = props[1];
107
+ var value = obj[prop];
108
+ if (!value) {
109
+ return null;
110
+ }
111
+ return deepGet(value, rest);
112
+ };
113
+ var sanitizeKeyword = function (keyword) {
114
+ var characters = [
115
+ '+',
116
+ '-',
117
+ '&&',
118
+ '||',
119
+ '!',
120
+ '(',
121
+ ')',
122
+ '{',
123
+ '}',
124
+ '[',
125
+ ']',
126
+ '^',
127
+ '~',
128
+ '*',
129
+ '?',
130
+ ':',
131
+ '/',
132
+ ];
133
+ characters.forEach(function (char) {
134
+ keyword = keyword.replace(char, ' ');
135
+ });
136
+ return keyword.replace(/\s+/g, ' ');
137
+ };
138
+
139
+ var keyword = (function (keyword, fields) {
140
+ if (!keyword) {
141
+ return null;
142
+ }
143
+ var sanitizeForES = function (value) {
144
+ return value
145
+ .split(' ')
146
+ .filter(Boolean)
147
+ .map(function (term) { return sanitizeKeyword(term) + "*"; })
148
+ .join(' ');
149
+ };
150
+ var splittedKeyword = keyword.split(':');
151
+ var sanitizedKeyword = splittedKeyword.length > 1
152
+ ? splittedKeyword[0] + ":" + sanitizeForES(splittedKeyword[1])
153
+ : sanitizeForES(keyword);
154
+ return {
155
+ query_string: {
156
+ query: sanitizedKeyword,
157
+ default_operator: 'AND',
158
+ fields: fields,
159
+ },
160
+ };
88
161
  });
89
162
 
90
163
  var filters = (function (filters) {
@@ -97,12 +170,28 @@ var filters = (function (filters) {
97
170
  : null;
98
171
  });
99
172
 
173
+ var sanitizeFilterItem = function (item) {
174
+ var _a = item.split(':'), key = _a[0], value = _a[1];
175
+ var sanitizedValue = sanitizeKeyword(value);
176
+ sanitizedValue = sanitizedValue
177
+ .split(' ')
178
+ .filter(Boolean)
179
+ .map(function (term) { return "" + term; })
180
+ .join(' ');
181
+ return key + ":" + sanitizedValue;
182
+ };
100
183
  var parseFilters = function (filters) {
101
184
  if (typeof filters === 'string') {
102
185
  return filters;
103
186
  }
104
187
  return filters
105
- .map(function (item) { return (typeof item === 'string' ? item : "(" + item.join(' OR ') + ")"); })
188
+ .map(function (item) {
189
+ if (typeof item === 'string') {
190
+ return sanitizeFilterItem(item);
191
+ }
192
+ var sanitizedItems = item.map(function (i) { return sanitizeFilterItem(i); });
193
+ return "(" + sanitizedItems.join(' OR ') + ")";
194
+ })
106
195
  .join(' AND ');
107
196
  };
108
197
  var facetFilters = (function (facetFilters) {
@@ -142,8 +231,8 @@ var buildQueryParams = function (settings, instantSearchParams) {
142
231
  .map(function (elem) { return parseFloat(elem.trim()); }), lat = _a[0], lng = _a[1];
143
232
  query.distance = Number(instantSearchParams.aroundRadius);
144
233
  query.distanceUnit = 'mi';
145
- query.eligibilityLat = lat;
146
- query.eligibilityLon = lng;
234
+ query.lat = lat;
235
+ query.lon = lng;
147
236
  }
148
237
  if (instantSearchParams.facets && instantSearchParams.facets.length) {
149
238
  query.aggregations = JSON.stringify(instantSearchParams.facets.reduce(function (aggregations, facet) {
@@ -183,48 +272,16 @@ var Query = (function () {
183
272
  ? this.options.restrictSearchableAttributes
184
273
  : this.settings.keywordSearchFields;
185
274
  };
275
+ Query.prototype.isSearchableAttributesRestricted = function () {
276
+ var _a;
277
+ return ((_a = this.options.restrictSearchableAttributes) === null || _a === void 0 ? void 0 : _a.length) > 0;
278
+ };
186
279
  Query.prototype.getNexus211QueryParams = function () {
187
280
  return buildQueryParams(this.settings, this.options);
188
281
  };
189
282
  return Query;
190
283
  }());
191
284
 
192
- var splitPath = function (path) {
193
- var idx = path.indexOf('.');
194
- if (idx === -1) {
195
- return [path];
196
- }
197
- return [path.slice(0, idx), path.slice(idx + 1)];
198
- };
199
- var deepSet = function (obj, path, value) {
200
- var props = splitPath(path);
201
- if (props.length === 1) {
202
- obj[props[0]] = value;
203
- return;
204
- }
205
- var prop = props[0], rest = props[1];
206
- if (!obj[prop]) {
207
- obj[prop] = {};
208
- }
209
- deepSet(obj[prop], rest, value);
210
- };
211
- var deepGet = function (obj, path) {
212
- var props = splitPath(path);
213
- if (props.length === 1) {
214
- var value_1 = obj[props[0]];
215
- if (typeof value_1 === 'undefined') {
216
- return null;
217
- }
218
- return value_1;
219
- }
220
- var prop = props[0], rest = props[1];
221
- var value = obj[prop];
222
- if (!value) {
223
- return null;
224
- }
225
- return deepGet(value, rest);
226
- };
227
-
228
285
  var wrapSubstringInTags = function (_a) {
229
286
  var text = _a.text, start = _a.start, length = _a.length, preTag = _a.preTag, postTag = _a.postTag;
230
287
  return [
@@ -267,6 +324,17 @@ var highlight = function (query, hit) {
267
324
  }
268
325
  deepSet(_highlightResult, field, matchTextWithQuery(value, query));
269
326
  });
327
+ if (query.isSearchableAttributesRestricted()) {
328
+ query.settings.keywordSearchFields.forEach(function (field) {
329
+ if (!deepGet(_highlightResult, field)) {
330
+ deepSet(_highlightResult, field, {
331
+ matchLevel: 'none',
332
+ matchedWords: [],
333
+ value: deepGet(hit, field),
334
+ });
335
+ }
336
+ });
337
+ }
270
338
  return __assign(__assign({}, hit), { _highlightResult: _highlightResult });
271
339
  };
272
340
 
@@ -315,6 +383,7 @@ var SearchClient = (function () {
315
383
  SearchClient.prototype.getDefaultSettings = function () {
316
384
  return {
317
385
  endpoint: 'https://admin.211cs.org',
386
+ searchUri: '/api/search',
318
387
  keywordSearchFields: [
319
388
  'service.name',
320
389
  'site.name',
@@ -347,7 +416,7 @@ var SearchClient = (function () {
347
416
  if (!this.settings.token) {
348
417
  throw new Error('You must provide a valid SearchApi or PublicSearchApi token. Visit https://admin.211cs.org to create one.');
349
418
  }
350
- return [4, fetch(this.settings.endpoint + "/api/search", {
419
+ return [4, fetch("" + this.settings.endpoint + this.settings.searchUri, {
351
420
  headers: {
352
421
  cache: 'no-cache',
353
422
  authorization: "SearchApi " + this.settings.token,
@@ -12,4 +12,4 @@ var SearchWidget=function(e){"use strict";
12
12
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
13
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
14
  PERFORMANCE OF THIS SOFTWARE.
15
- ***************************************************************************** */var t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function n(e,t,n,r){return new(n||(n=Promise))((function(i,a){function o(e){try{s(r.next(e))}catch(e){a(e)}}function c(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,c)}s((r=r.apply(e,t||[])).next())}))}function r(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=o.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){o.label=a[1];break}if(6===a[0]&&o.label<i[1]){o.label=i[1],i=a;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(a);break}i[2]&&o.ops.pop(),o.trys.pop();continue}a=t.call(e,o)}catch(e){a=[6,e],r=0}finally{n=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}function i(e,t,n){if(n||2===arguments.length)for(var r,i=0,a=t.length;i<a;i++)!r&&i in t||(r||(r=Array.prototype.slice.call(t,0,i)),r[i]=t[i]);return e.concat(r||t)}var a=function(e,t){return e?{query_string:{query:e+"*",default_operator:"AND",fields:t}}:null},o=function(e){return e?{query_string:{query:""+e}}:null},c=function(e){return"string"==typeof e?e:e.map((function(e){return"string"==typeof e?e:"("+e.join(" OR ")+")"})).join(" AND ")},s=function(e){return e&&e.length?{query_string:{query:c(e)}}:null},u=function(e,t){var n=function(e,t){var n=[a(t.query,t.restrictSearchableAttributes?t.restrictSearchableAttributes:e.keywordSearchFields),o(t.filters),s(t.facetFilters)].filter((function(e){return null!==e}));return n.length?n:"*"}(e,t),r={query:"string"==typeof n?n:JSON.stringify(n)},c=t.hitsPerPage||20;if(r.$limit=c,r.$skip=c&&c*t.page||0,t.aroundLatLng&&t.aroundRadius){var u=t.aroundLatLng.split(",",2).map((function(e){return parseFloat(e.trim())})),l=u[0],f=u[1];r.distance=Number(t.aroundRadius),r.distanceUnit="mi",r.eligibilityLat=l,r.eligibilityLon=f}return t.facets&&t.facets.length&&(r.aggregations=JSON.stringify(t.facets.reduce((function(e,n){if(e[n]={terms:{field:n+".keyword",min_doc_count:0,size:100}},t.facetQuery){var r=i(i([".*"],t.facetQuery.split("").map((function(e){return"["+e.toLocaleLowerCase()+e.toLocaleUpperCase()+"]"}))),[".*"]).join("");e[n].terms.include=r}return e}),{}))),r},l=function(){function e(e,t){this.settings=e,this.options=t,this.body=this.getNexus211QueryParams()}return e.prototype.getKeywordSearchFields=function(){return this.options.restrictSearchableAttributes?this.options.restrictSearchableAttributes:this.settings.keywordSearchFields},e.prototype.getNexus211QueryParams=function(){return u(this.settings,this.options)},e}(),f=function(e){var t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]},h=function(e,t,n){var r=f(t);if(1!==r.length){var i=r[0],a=r[1];e[i]||(e[i]={}),h(e[i],a,n)}else e[r[0]]=n},d=function(e,t){var n=f(t);if(1===n.length){var r=e[n[0]];return void 0===r?null:r}var i=n[0],a=n[1],o=e[i];return o?d(o,a):null},p=function(e,n){return n.map((function(n){return function(e,n){var r={};return e.getKeywordSearchFields().forEach((function(t){var i=d(n,t);i&&h(r,t,function(e,t){var n,r,i,a,o,c,s=t.options.query,u=e.toLowerCase().search(s.toLowerCase());return-1===u?{matchLevel:"none",matchedWords:[],value:e}:{fullyHighlighted:0===u&&e.length===s.length,matchLevel:"full",matchedWords:[s],value:(n={text:e,start:u,length:s.length,preTag:t.options.highlightPreTag,postTag:t.options.highlightPostTag},r=n.text,i=n.start,a=n.length,o=n.preTag,c=n.postTag,[r.slice(0,i),o,r.substr(i,a),c,r.slice(i+a)].join(""))}}(i,e))})),t(t({},n),{_highlightResult:r})}(e,t({objectID:n.id},n))}))},g=function(e){return e.aggregations?Object.entries(e.aggregations).reduce((function(e,t){var n=t[0],r=t[1];return e[n]=r.buckets.reduce((function(e,t){return e[t.key]=t.doc_count,e}),{}),e}),{}):{}},m=function(e,t){return{results:[{index:"instant_search",query:e.options.query,params:e.body.query,nbHits:t.__meta.total,hits:p(e,t.data),hitsPerPage:+t.__meta.perPage,page:e.options.page,nbPages:t.__meta.perPage?Math.ceil(t.__meta.total/t.__meta.perPage):0,processingTimeMS:1,exhaustiveNbHits:!0,exhaustiveFacetsCount:!0,facets:g(t)}]}},v=function(){function e(e){this.settings=t(t({},this.getDefaultSettings()),e)}return e.prototype.getDefaultSettings=function(){return{endpoint:"https://admin.211cs.org",keywordSearchFields:["service.name","site.name","site.agency.name","site.agency.description"]}},e.prototype.search=function(e){return n(this,void 0,void 0,(function(){var t,n;return r(this,(function(r){switch(r.label){case 0:return t=new l(this.settings,e[0].params),[4,this.makeSearchRequest(t.body)];case 1:return n=r.sent(),[2,m(t,n)]}}))}))},e.prototype.makeSearchRequest=function(e){return n(this,void 0,void 0,(function(){var t,n;return r(this,(function(r){switch(r.label){case 0:if(!this.settings.token)throw new Error("You must provide a valid SearchApi or PublicSearchApi token. Visit https://admin.211cs.org to create one.");return[4,fetch(this.settings.endpoint+"/api/search",{headers:{cache:"no-cache",authorization:"SearchApi "+this.settings.token,"content-type":"application/json"},method:"POST",body:JSON.stringify({search:e})})];case 1:if(200!==(t=r.sent()).status)throw n=t.text(),new Error("Unexpected status "+t.status+": "+n);return[2,t.json()]}}))}))},e.prototype.searchForFacetValues=function(e){return n(this,void 0,void 0,(function(){var i=this;return r(this,(function(a){return[2,Promise.all(e.map((function(a){return n(i,void 0,void 0,(function(){var n;return r(this,(function(r){switch(r.label){case 0:return n=new l(this.settings,t(t({},e[0].params),{facets:[e[0].params.facetName],hitsPerPage:0})),[4,this.makeSearchRequest(n.body)];case 1:return[2,{facetHits:r.sent().aggregations[a.params.facetName].buckets.map((function(e){return{value:e.key,highlighted:e.key,count:e.doc_count,isRefined:!1}})),exhaustiveFacetsCount:!0,processingTimeMS:1}]}}))}))})))]}))}))},e.prototype.addAlgoliaAgent=function(e,t){console.warn("Unhandled addAlgoliaAgent",e,t)},e.prototype.clearCache=function(){return console.warn("Unhandled clearCache"),Promise.resolve()},e}(),y=function(e){var t=e.map((function(e){return e.hit})),n=e[0],r=n.lat,i=n.lng;return{hits:t,lat:r,lng:i,key:r+"_"+i}},b=function(e){switch(typeof e){case"string":return parseFloat(e);case"number":return e;default:return null}},S=function(e){return(e.site.addresses||[]).map((function(n){return{lat:n.lat,lng:n.lng,hit:t(t({},e),{site:t(t({},e.site),{addresses:[n]})})}}))},L=function(e,t){return function(n){var r,i=n.container,a=n.attribute,o=n.placeholder||"",c=(r=n.debounce||200,function(e){var t=null;return function(n){null!==t&&(clearTimeout(t),t=null);var i=n.target.value;t=setTimeout((function(){e(i),t=null}),r)}}),s=t&&"number"===t?"number":"search",u=e?"":"*";return{init:function(e){var t=e.helper;i.innerHTML='<input class="ais-SearchBox-input" type='+s+" placeholder="+o+' autocomplete="off" autocorrect="off" autocapitalize="off" maxlength="512">',i.querySelector("input").addEventListener("input",c((function(e){t.clearRefinements(a),e&&t.addFacetRefinement(a,[e+u]),t.search()})))},getWidgetSearchParameters:function(e){return e.addFacet(a)}}}},k=function(e){return'<li class="ais-RefinementList-item">\n <label class="ais-RefinementList-label">\n <input class="ais-RefinementList-checkbox" type="checkbox" value='+e+' />\n <span class="ais-RefinementList-labelText">'+e+" miles</span>\n </label>\n </li>"},w=L(!0,"number"),R=L(!0,"string"),x=L(!1,"string"),P=function(){};function _(e,n){return void 0===n&&(n=P),function(r){var i=r.attribute,a=r.transformItems,o=void 0===a?function(e){return e}:a;return{$$type:"cs.taxonomyRefinementList",init:function(n){e(t(t({},this.getWidgetRenderState(n)),{instantSearchInstance:n.instantSearchInstance}),!0)},render:function(n){e(t(t({},this.getWidgetRenderState(n)),{instantSearchInstance:n.instantSearchInstance}),!1)},getRenderState:function(e,n){var r;return t(t({},e),{taxonomyRefinementList:t(t({},e.taxonomyRefinementList),(r={},r[i]=this.getWidgetRenderState(n),r))})},getWidgetRenderState:function(e){var t=e.results,n=e.helper,a=function(e){e.split("|").forEach((function(e){return n.isDisjunctiveRefined(i,e)?n.removeDisjunctiveFacetRefinement(i,e):n.addDisjunctiveFacetRefinement(i,e)})),n.search()};return t?{items:o(t.getRefinements(i)),refine:a,widgetParams:r}:{items:[],refine:a,widgetParams:r}},getWidgetUiState:function(e,n){var r,a=n.searchParameters;return t(t({},e),{taxonomyRefinementList:t(t({},e.taxonomyRefinementList),(r={},r[i]=a.getRefinements(i),r))})},getWidgetSearchParameters:function(e){return e.addDisjunctiveFacet(i)},dispose:function(){n()}}}}var j=function(e){return{render:function(t,n){var r=t.items,i=t.refine,a="string"==typeof e.container?document.querySelector(e.container):e.container;if(n)a.addEventListener("click",(function(e){if(e.target instanceof HTMLElement){var t=e.target.closest("input");t&&i(t.value)}}));else{var o=e.items.map((function(e){var t=e.label,n=e.value,i=n.split("|").every((function(e){return r.find((function(t){return"disjunctive"===t.type&&t.name===e}))}));return'\n <li>\n <label>\n <input\n type="checkbox"\n value="'+n+'"\n '+(i?"checked":"")+"\n />\n "+t+"\n </label>\n </li>\n "}));a.innerHTML="<ul>"+o.join("")+"</ul>"}},dispose:function(){}}};return e.SearchClient=v,e.connectTaxonomyRefinementList=_,e.createTaxonomyRefinementListRenderer=j,e.exactNumberFieldSearch=w,e.exactStringFieldSearch=R,e.googleMaps=function(e){var n=e.container,r=e.renderInfo,i=e.mapFunc;i=i||S;var a="string"==typeof n?document.querySelector(n):n,o=null,c="",s={},u=new google.maps.InfoWindow;return{init:function(){o=new google.maps.Map(a,{})},render:function(e){if(o){var n=function(e,t,n){var r={};return e.forEach((function(e){var n=t(e);r[n]||(r[n]=[]),r[n].push(e)})),Object.keys(r).forEach((function(e){r[e]=n(r[e])})),r}(function(e,n){return(r=e.map(n),i=[],r.forEach((function(e){i=i.concat(e)})),i).map((function(e){return t(t({},e),{lat:b(e.lat),lng:b(e.lng)})})).filter((function(e){return null!==e.lat&&null!==e.lng}));var r,i}(e.results.hits,i),(function(e){return e.lat+"_"+e.lng}),y),a=Object.keys(n).sort((function(e,t){return e.localeCompare(t)})).join(",");a!==c&&(c=a,Object.keys(s).forEach((function(e){n[e]||(s[e].marker.setMap(null),delete s[e])})),Object.keys(n).forEach((function(e){if(!s[e]){var t=n[e],i=t.lat,a=t.lng,c=new google.maps.Marker({position:{lat:i,lng:a},map:o});r&&c.addListener("click",(function(){u.setContent(r(n[e])),u.open(o,c)})),s[e]={marker:c,data:n[e]}}})),function(e,t){var n=new google.maps.LatLngBounds;Object.keys(t).forEach((function(e){var r=t[e];n.extend(new google.maps.LatLng(r.lat,r.lng))})),e.fitBounds(n)}(o,n))}},dispose:function(e){},getWidgetState:function(e,t){return e},getWidgetSearchParameters:function(e,t){return e}}},e.locationDistanceFilter=function(e){var t=e.container,n=e.miles||[5,10,20,50];return{init:function(e){var r=e.helper,i=n.map(k).join("\n");t.innerHTML='<div class="ais-RefinementList">\n <ul class="ais-RefinementList-list">\n '+i+"\n </ul>\n </div>";var a=t.querySelectorAll("input[type=checkbox]");a.forEach((function(e){e.addEventListener("change",(function(t){var n=!1;a.forEach((function(t){t.value!==e.value&&(t.checked=!1),t.checked&&(n=!0)})),n?r.setQueryParameter("aroundRadius",t.target.value).search():r.setQueryParameter("aroundRadius").search()}))}))}}},e.makeFieldSearch=L,e.noop=P,e.placeAutocomplete=function(e){var t=e.container,n=e.placeholder;return{init:function(e){var r=e.helper;t.innerHTML='<input class="ais-SearchBox-input" type="search" placeholder='+n+"/>";var i=t.querySelector("input[type=search]"),a=new google.maps.places.Autocomplete(i);a.setFields(["place_id","geometry","name","formatted_address"]);var o=new google.maps.Geocoder;a.addListener("place_changed",(function(){var e=a.getPlace();""!==e.name?e.place_id&&o.geocode({placeId:e.place_id},(function(e,t){if("OK"===t){var n=e[0].geometry.location;r.setQueryParameter("aroundLatLng",n.lat()+", "+n.lng()).search()}else console.warn("Geocoder failed due to: "+t)})):r.setQueryParameter("aroundLatLng").search()}))}}},e.searchBoxFields=function(e){return{init:function(t){e.container.innerHTML='<div class="ais-RefinementList">\n <ul class="ais-RefinementList-list">\n '+e.attributes.map((function(e){return function(e){return'<li class="ais-RefinementList-item">\n <label class="ais-RefinementList-label">\n <input class="ais-RefinementList-checkbox" type="checkbox" value="'+e.fieldName+'" checked />\n <span class="ais-RefinementList-labelText">'+e.title+"</span>\n </label>\n </li>"}(e)})).join("\n")+"\n </ul>\n </div>";e.container.querySelectorAll("input[type=checkbox]").forEach((function(n){n.addEventListener("change",(function(){!function(){var n=e.container.querySelectorAll("input[type=checkbox]:checked");if(n.length){for(var r=[],i=0;i<n.length;i+=1)r.push(n[i].getAttribute("value"));t.helper.setQueryParameter("restrictSearchableAttributes",r)}else t.helper.setQueryParameter("restrictSearchableAttributes");t.helper.search()}()}))}))}}},e.stringFieldSearch=x,e.taxonomyRefinementList=function(e){var n=j(e),r=_(n.render,n.dispose);return t(t({},r(e)),{$$widgetType:"cs.taxonomyRefinementList"})},Object.defineProperty(e,"__esModule",{value:!0}),e}({});
15
+ ***************************************************************************** */var t=function(){return(t=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var i in t=arguments[n])Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i]);return e}).apply(this,arguments)};function n(e,t,n,r){return new(n||(n=Promise))((function(i,a){function o(e){try{s(r.next(e))}catch(e){a(e)}}function c(e){try{s(r.throw(e))}catch(e){a(e)}}function s(e){var t;e.done?i(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(o,c)}s((r=r.apply(e,t||[])).next())}))}function r(e,t){var n,r,i,a,o={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return a={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function c(a){return function(c){return function(a){if(n)throw new TypeError("Generator is already executing.");for(;o;)try{if(n=1,r&&(i=2&a[0]?r.return:a[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,a[1])).done)return i;switch(r=0,i&&(a=[2&a[0],i.value]),a[0]){case 0:case 1:i=a;break;case 4:return o.label++,{value:a[1],done:!1};case 5:o.label++,r=a[1],a=[0];continue;case 7:a=o.ops.pop(),o.trys.pop();continue;default:if(!(i=o.trys,(i=i.length>0&&i[i.length-1])||6!==a[0]&&2!==a[0])){o=0;continue}if(3===a[0]&&(!i||a[1]>i[0]&&a[1]<i[3])){o.label=a[1];break}if(6===a[0]&&o.label<i[1]){o.label=i[1],i=a;break}if(i&&o.label<i[2]){o.label=i[2],o.ops.push(a);break}i[2]&&o.ops.pop(),o.trys.pop();continue}a=t.call(e,o)}catch(e){a=[6,e],r=0}finally{n=i=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}function i(e,t,n){if(n||2===arguments.length)for(var r,i=0,a=t.length;i<a;i++)!r&&i in t||(r||(r=Array.prototype.slice.call(t,0,i)),r[i]=t[i]);return e.concat(r||t)}var a=function(e){var t=e.indexOf(".");return-1===t?[e]:[e.slice(0,t),e.slice(t+1)]},o=function(e,t,n){var r=a(t);if(1!==r.length){var i=r[0],c=r[1];e[i]||(e[i]={}),o(e[i],c,n)}else e[r[0]]=n},c=function(e,t){var n=a(t);if(1===n.length){var r=e[n[0]];return void 0===r?null:r}var i=n[0],o=n[1],s=e[i];return s?c(s,o):null},s=function(e){return["+","-","&&","||","!","(",")","{","}","[","]","^","~","*","?",":","/"].forEach((function(t){e=e.replace(t," ")})),e.replace(/\s+/g," ")},u=function(e,t){if(!e)return null;var n=function(e){return e.split(" ").filter(Boolean).map((function(e){return s(e)+"*"})).join(" ")},r=e.split(":");return{query_string:{query:r.length>1?r[0]+":"+n(r[1]):n(e),default_operator:"AND",fields:t}}},l=function(e){return e?{query_string:{query:""+e}}:null},f=function(e){var t=e.split(":"),n=t[0],r=t[1],i=s(r);return n+":"+(i=i.split(" ").filter(Boolean).map((function(e){return""+e})).join(" "))},h=function(e){return"string"==typeof e?e:e.map((function(e){return"string"==typeof e?f(e):"("+e.map((function(e){return f(e)})).join(" OR ")+")"})).join(" AND ")},p=function(e){return e&&e.length?{query_string:{query:h(e)}}:null},d=function(e,t){var n=function(e,t){var n=[u(t.query,t.restrictSearchableAttributes?t.restrictSearchableAttributes:e.keywordSearchFields),l(t.filters),p(t.facetFilters)].filter((function(e){return null!==e}));return n.length?n:"*"}(e,t),r={query:"string"==typeof n?n:JSON.stringify(n)},a=t.hitsPerPage||20;if(r.$limit=a,r.$skip=a&&a*t.page||0,t.aroundLatLng&&t.aroundRadius){var o=t.aroundLatLng.split(",",2).map((function(e){return parseFloat(e.trim())})),c=o[0],s=o[1];r.distance=Number(t.aroundRadius),r.distanceUnit="mi",r.lat=c,r.lon=s}return t.facets&&t.facets.length&&(r.aggregations=JSON.stringify(t.facets.reduce((function(e,n){if(e[n]={terms:{field:n+".keyword",min_doc_count:0,size:100}},t.facetQuery){var r=i(i([".*"],t.facetQuery.split("").map((function(e){return"["+e.toLocaleLowerCase()+e.toLocaleUpperCase()+"]"}))),[".*"]).join("");e[n].terms.include=r}return e}),{}))),r},g=function(){function e(e,t){this.settings=e,this.options=t,this.body=this.getNexus211QueryParams()}return e.prototype.getKeywordSearchFields=function(){return this.options.restrictSearchableAttributes?this.options.restrictSearchableAttributes:this.settings.keywordSearchFields},e.prototype.isSearchableAttributesRestricted=function(){var e;return(null===(e=this.options.restrictSearchableAttributes)||void 0===e?void 0:e.length)>0},e.prototype.getNexus211QueryParams=function(){return d(this.settings,this.options)},e}(),m=function(e,n){return n.map((function(n){return function(e,n){var r={};return e.getKeywordSearchFields().forEach((function(t){var i=c(n,t);i&&o(r,t,function(e,t){var n,r,i,a,o,c,s=t.options.query,u=e.toLowerCase().search(s.toLowerCase());return-1===u?{matchLevel:"none",matchedWords:[],value:e}:{fullyHighlighted:0===u&&e.length===s.length,matchLevel:"full",matchedWords:[s],value:(n={text:e,start:u,length:s.length,preTag:t.options.highlightPreTag,postTag:t.options.highlightPostTag},r=n.text,i=n.start,a=n.length,o=n.preTag,c=n.postTag,[r.slice(0,i),o,r.substr(i,a),c,r.slice(i+a)].join(""))}}(i,e))})),e.isSearchableAttributesRestricted()&&e.settings.keywordSearchFields.forEach((function(e){c(r,e)||o(r,e,{matchLevel:"none",matchedWords:[],value:c(n,e)})})),t(t({},n),{_highlightResult:r})}(e,t({objectID:n.id},n))}))},v=function(e){return e.aggregations?Object.entries(e.aggregations).reduce((function(e,t){var n=t[0],r=t[1];return e[n]=r.buckets.reduce((function(e,t){return e[t.key]=t.doc_count,e}),{}),e}),{}):{}},y=function(e,t){return{results:[{index:"instant_search",query:e.options.query,params:e.body.query,nbHits:t.__meta.total,hits:m(e,t.data),hitsPerPage:+t.__meta.perPage,page:e.options.page,nbPages:t.__meta.perPage?Math.ceil(t.__meta.total/t.__meta.perPage):0,processingTimeMS:1,exhaustiveNbHits:!0,exhaustiveFacetsCount:!0,facets:v(t)}]}},b=function(){function e(e){this.settings=t(t({},this.getDefaultSettings()),e)}return e.prototype.getDefaultSettings=function(){return{endpoint:"https://admin.211cs.org",searchUri:"/api/search",keywordSearchFields:["service.name","site.name","site.agency.name","site.agency.description"]}},e.prototype.search=function(e){return n(this,void 0,void 0,(function(){var t,n;return r(this,(function(r){switch(r.label){case 0:return t=new g(this.settings,e[0].params),[4,this.makeSearchRequest(t.body)];case 1:return n=r.sent(),[2,y(t,n)]}}))}))},e.prototype.makeSearchRequest=function(e){return n(this,void 0,void 0,(function(){var t,n;return r(this,(function(r){switch(r.label){case 0:if(!this.settings.token)throw new Error("You must provide a valid SearchApi or PublicSearchApi token. Visit https://admin.211cs.org to create one.");return[4,fetch(""+this.settings.endpoint+this.settings.searchUri,{headers:{cache:"no-cache",authorization:"SearchApi "+this.settings.token,"content-type":"application/json"},method:"POST",body:JSON.stringify({search:e})})];case 1:if(200!==(t=r.sent()).status)throw n=t.text(),new Error("Unexpected status "+t.status+": "+n);return[2,t.json()]}}))}))},e.prototype.searchForFacetValues=function(e){return n(this,void 0,void 0,(function(){var i=this;return r(this,(function(a){return[2,Promise.all(e.map((function(a){return n(i,void 0,void 0,(function(){var n;return r(this,(function(r){switch(r.label){case 0:return n=new g(this.settings,t(t({},e[0].params),{facets:[e[0].params.facetName],hitsPerPage:0})),[4,this.makeSearchRequest(n.body)];case 1:return[2,{facetHits:r.sent().aggregations[a.params.facetName].buckets.map((function(e){return{value:e.key,highlighted:e.key,count:e.doc_count,isRefined:!1}})),exhaustiveFacetsCount:!0,processingTimeMS:1}]}}))}))})))]}))}))},e.prototype.addAlgoliaAgent=function(e,t){console.warn("Unhandled addAlgoliaAgent",e,t)},e.prototype.clearCache=function(){return console.warn("Unhandled clearCache"),Promise.resolve()},e}(),S=function(e){var t=e.map((function(e){return e.hit})),n=e[0],r=n.lat,i=n.lng;return{hits:t,lat:r,lng:i,key:r+"_"+i}},L=function(e){switch(typeof e){case"string":return parseFloat(e);case"number":return e;default:return null}},k=function(e){return(e.site.addresses||[]).map((function(n){return{lat:n.lat,lng:n.lng,hit:t(t({},e),{site:t(t({},e.site),{addresses:[n]})})}}))},R=function(e,t){return function(n){var r,i=n.container,a=n.attribute,o=n.placeholder||"",c=(r=n.debounce||200,function(e){var t=null;return function(n){null!==t&&(clearTimeout(t),t=null);var i=n.target.value;t=setTimeout((function(){e(i),t=null}),r)}}),s=t&&"number"===t?"number":"search",u=e?"":"*";return{init:function(e){var t=e.helper;i.innerHTML='<input class="ais-SearchBox-input" type='+s+" placeholder="+o+' autocomplete="off" autocorrect="off" autocapitalize="off" maxlength="512">',i.querySelector("input").addEventListener("input",c((function(e){t.clearRefinements(a),e&&t.addFacetRefinement(a,[e+u]),t.search()})))},getWidgetSearchParameters:function(e){return e.addFacet(a)}}}},w=function(e){return'<li class="ais-RefinementList-item">\n <label class="ais-RefinementList-label">\n <input class="ais-RefinementList-checkbox" type="checkbox" value='+e+' />\n <span class="ais-RefinementList-labelText">'+e+" miles</span>\n </label>\n </li>"},x=R(!0,"number"),P=R(!0,"string"),_=R(!1,"string"),j=function(){};function F(e,n){return void 0===n&&(n=j),function(r){var i=r.attribute,a=r.transformItems,o=void 0===a?function(e){return e}:a;return{$$type:"cs.taxonomyRefinementList",init:function(n){e(t(t({},this.getWidgetRenderState(n)),{instantSearchInstance:n.instantSearchInstance}),!0)},render:function(n){e(t(t({},this.getWidgetRenderState(n)),{instantSearchInstance:n.instantSearchInstance}),!1)},getRenderState:function(e,n){var r;return t(t({},e),{taxonomyRefinementList:t(t({},e.taxonomyRefinementList),(r={},r[i]=this.getWidgetRenderState(n),r))})},getWidgetRenderState:function(e){var t=e.results,n=e.helper,a=function(e){e.split("|").forEach((function(e){return n.isDisjunctiveRefined(i,e)?n.removeDisjunctiveFacetRefinement(i,e):n.addDisjunctiveFacetRefinement(i,e)})),n.search()};return t?{items:o(t.getRefinements(i)),refine:a,widgetParams:r}:{items:[],refine:a,widgetParams:r}},getWidgetUiState:function(e,n){var r,a=n.searchParameters;return t(t({},e),{taxonomyRefinementList:t(t({},e.taxonomyRefinementList),(r={},r[i]=a.getRefinements(i),r))})},getWidgetSearchParameters:function(e){return e.addDisjunctiveFacet(i)},dispose:function(){n()}}}}var A=function(e){return{render:function(t,n){var r=t.items,i=t.refine,a="string"==typeof e.container?document.querySelector(e.container):e.container;if(n)a.addEventListener("click",(function(e){if(e.target instanceof HTMLElement){var t=e.target.closest("input");t&&i(t.value)}}));else{var o=e.items.map((function(e){var t=e.label,n=e.value,i=n.split("|").every((function(e){return r.find((function(t){return"disjunctive"===t.type&&t.name===e}))}));return'\n <li>\n <label>\n <input\n type="checkbox"\n value="'+n+'"\n '+(i?"checked":"")+"\n />\n "+t+"\n </label>\n </li>\n "}));a.innerHTML="<ul>"+o.join("")+"</ul>"}},dispose:function(){}}};return e.SearchClient=b,e.connectTaxonomyRefinementList=F,e.createTaxonomyRefinementListRenderer=A,e.exactNumberFieldSearch=x,e.exactStringFieldSearch=P,e.googleMaps=function(e){var n=e.container,r=e.renderInfo,i=e.mapFunc;i=i||k;var a="string"==typeof n?document.querySelector(n):n,o=null,c="",s={},u=new google.maps.InfoWindow;return{init:function(){o=new google.maps.Map(a,{})},render:function(e){if(o){var n=function(e,t,n){var r={};return e.forEach((function(e){var n=t(e);r[n]||(r[n]=[]),r[n].push(e)})),Object.keys(r).forEach((function(e){r[e]=n(r[e])})),r}(function(e,n){return(r=e.map(n),i=[],r.forEach((function(e){i=i.concat(e)})),i).map((function(e){return t(t({},e),{lat:L(e.lat),lng:L(e.lng)})})).filter((function(e){return null!==e.lat&&null!==e.lng}));var r,i}(e.results.hits,i),(function(e){return e.lat+"_"+e.lng}),S),a=Object.keys(n).sort((function(e,t){return e.localeCompare(t)})).join(",");a!==c&&(c=a,Object.keys(s).forEach((function(e){n[e]||(s[e].marker.setMap(null),delete s[e])})),Object.keys(n).forEach((function(e){if(!s[e]){var t=n[e],i=t.lat,a=t.lng,c=new google.maps.Marker({position:{lat:i,lng:a},map:o});r&&c.addListener("click",(function(){u.setContent(r(n[e])),u.open(o,c)})),s[e]={marker:c,data:n[e]}}})),function(e,t){var n=new google.maps.LatLngBounds;Object.keys(t).forEach((function(e){var r=t[e];n.extend(new google.maps.LatLng(r.lat,r.lng))})),e.fitBounds(n)}(o,n))}},dispose:function(e){},getWidgetState:function(e,t){return e},getWidgetSearchParameters:function(e,t){return e}}},e.locationDistanceFilter=function(e){var t=e.container,n=e.miles||[5,10,20,50];return{init:function(e){var r=e.helper,i=n.map(w).join("\n");t.innerHTML='<div class="ais-RefinementList">\n <ul class="ais-RefinementList-list">\n '+i+"\n </ul>\n </div>";var a=t.querySelectorAll("input[type=checkbox]");a.forEach((function(e){e.addEventListener("change",(function(t){var n=!1;a.forEach((function(t){t.value!==e.value&&(t.checked=!1),t.checked&&(n=!0)})),n?r.setQueryParameter("aroundRadius",t.target.value).search():r.setQueryParameter("aroundRadius").search()}))}))}}},e.makeFieldSearch=R,e.noop=j,e.placeAutocomplete=function(e){var t=e.container,n=e.placeholder;return{init:function(e){var r=e.helper;t.innerHTML='<input class="ais-SearchBox-input" type="search" placeholder='+n+"/>";var i=t.querySelector("input[type=search]"),a=new google.maps.places.Autocomplete(i);a.setFields(["place_id","geometry","name","formatted_address"]);var o=new google.maps.Geocoder;a.addListener("place_changed",(function(){var e=a.getPlace();""!==e.name?e.place_id&&o.geocode({placeId:e.place_id},(function(e,t){if("OK"===t){var n=e[0].geometry.location;r.setQueryParameter("aroundLatLng",n.lat()+", "+n.lng()).search()}else console.warn("Geocoder failed due to: "+t)})):r.setQueryParameter("aroundLatLng").search()}))}}},e.searchBoxFields=function(e){return{init:function(t){e.container.innerHTML='<div class="ais-RefinementList">\n <ul class="ais-RefinementList-list">\n '+e.attributes.map((function(e){return function(e){return'<li class="ais-RefinementList-item">\n <label class="ais-RefinementList-label">\n <input class="ais-RefinementList-checkbox" type="checkbox" value="'+e.fieldName+'" checked />\n <span class="ais-RefinementList-labelText">'+e.title+"</span>\n </label>\n </li>"}(e)})).join("\n")+"\n </ul>\n </div>";e.container.querySelectorAll("input[type=checkbox]").forEach((function(n){n.addEventListener("change",(function(){!function(){var n=e.container.querySelectorAll("input[type=checkbox]:checked");if(n.length){for(var r=[],i=0;i<n.length;i+=1)r.push(n[i].getAttribute("value"));t.helper.setQueryParameter("restrictSearchableAttributes",r)}else t.helper.setQueryParameter("restrictSearchableAttributes");t.helper.search()}()}))}))}}},e.stringFieldSearch=_,e.taxonomyRefinementList=function(e){var n=A(e),r=F(n.render,n.dispose);return t(t({},r(e)),{$$widgetType:"cs.taxonomyRefinementList"})},Object.defineProperty(e,"__esModule",{value:!0}),e}({});
@@ -11,5 +11,6 @@ export declare class Query {
11
11
  facetQuery?: string;
12
12
  });
13
13
  getKeywordSearchFields(): readonly string[];
14
+ isSearchableAttributesRestricted(): boolean;
14
15
  protected getNexus211QueryParams(): SearchQueryParams;
15
16
  }
@@ -2,6 +2,7 @@ import { FieldSettings } from './FieldSettings';
2
2
  export interface SearchClientSettings {
3
3
  endpoint: string;
4
4
  token: string;
5
+ searchUri?: string;
5
6
  fieldSettings?: FieldSettings;
6
7
  keywordSearchFields: string[];
7
8
  }
@@ -1,2 +1,3 @@
1
1
  export declare const deepSet: <T>(obj: Record<string, any>, path: string, value: T) => void;
2
2
  export declare const deepGet: (obj: Record<string, any>, path: string) => any;
3
+ export declare const sanitizeKeyword: (keyword: any) => any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@211la/search-client",
3
- "version": "0.3.3",
3
+ "version": "0.3.7",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/types/index.d.ts",
6
6
  "files": [