New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@internetarchive/search-service

Package Overview
Dependencies
Maintainers
17
Versions
158
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@internetarchive/search-service - npm Package Compare versions

Comparing version 0.4.5 to 0.4.6-alpha.2

dist/test/models/aggregation.test.d.ts

0

demo/app-root.ts

@@ -0,0 +0,0 @@ import { html, css, LitElement, TemplateResult, CSSResult, nothing } from 'lit';

@@ -0,0 +0,0 @@ import { __decorate } from "tslib";

@@ -19,3 +19,7 @@ /**

*/
ALPHABETICAL = 1
ALPHABETICAL = 1,
/**
* Sort descending numerically by key
*/
NUMERIC = 2
}

@@ -56,6 +60,14 @@ export interface AggregationOptions {

* @param sortType What to sort the buckets on.
* Accepted values are `AggregationSortType.COUNT` (descending order) and
* `AggregationSortType.ALPHABETICAL` (ascending order).
* Accepted values are:
* - `AggregationSortType.COUNT` (descending order)
* - `AggregationSortType.ALPHABETICAL` (ascending order)
* - `AggregationSortType.NUMERIC` (descending order)
*/
getSortedBuckets(sortType?: AggregationSortType): Bucket[] | number[];
/**
* Type guard for number[] buckets, since the buckets provided by the PPS
* may be either keyed objects or just an array of numbers. Currently only
* `year_histogram` facets are of the latter type.
*/
private isRawNumberBuckets;
}

35

dist/src/models/aggregation.js

@@ -13,2 +13,6 @@ import { __decorate } from "tslib";

AggregationSortType[AggregationSortType["ALPHABETICAL"] = 1] = "ALPHABETICAL";
/**
* Sort descending numerically by key
*/
AggregationSortType[AggregationSortType["NUMERIC"] = 2] = "NUMERIC";
})(AggregationSortType || (AggregationSortType = {}));

@@ -37,11 +41,16 @@ /**

* @param sortType What to sort the buckets on.
* Accepted values are `AggregationSortType.COUNT` (descending order) and
* `AggregationSortType.ALPHABETICAL` (ascending order).
* Accepted values are:
* - `AggregationSortType.COUNT` (descending order)
* - `AggregationSortType.ALPHABETICAL` (ascending order)
* - `AggregationSortType.NUMERIC` (descending order)
*/
getSortedBuckets(sortType) {
// Don't apply sorts to numeric buckets.
const copiedBuckets = [...this.buckets];
// Don't apply sorts to number[] aggregations (like year_histogram).
// Note this _doesn't_ apply to ordinary year aggregations, which have
// keyed buckets just like most other facet types.
// Assumption here is that all the buckets have the same type as the
// first bucket (which should be true in principle).
if (typeof this.buckets[0] === 'number') {
return [...this.buckets];
if (this.isRawNumberBuckets(copiedBuckets)) {
return copiedBuckets;
}

@@ -52,11 +61,23 @@ // Default locale & collation options

case AggregationSortType.ALPHABETICAL:
return [...this.buckets].sort((a, b) => {
return copiedBuckets.sort((a, b) => {
return collator.compare(a.key.toString(), b.key.toString());
});
case AggregationSortType.NUMERIC:
return copiedBuckets.sort((a, b) => {
return Number(b.key) - Number(a.key);
});
case AggregationSortType.COUNT:
default:
// Sorted by count by default
return [...this.buckets];
return copiedBuckets;
}
}
/**
* Type guard for number[] buckets, since the buckets provided by the PPS
* may be either keyed objects or just an array of numbers. Currently only
* `year_histogram` facets are of the latter type.
*/
isRawNumberBuckets(buckets) {
return typeof this.buckets[0] === 'number';
}
}

@@ -63,0 +84,0 @@ __decorate([

@@ -23,2 +23,3 @@ /**

aggregations_size?: number;
uid?: string;
}

@@ -17,2 +17,4 @@ import { SearchBackendInterface } from './search-backend-interface';

protected requestScope?: string;
protected cachingFlags?: string;
protected verbose?: boolean;
protected debuggingEnabled?: boolean;

@@ -32,2 +34,6 @@ constructor(options?: SearchBackendOptionsInterface);

/**
* Logs a full response to the console, with truncated hits.
*/
private printResponse;
/**
* Logs PPS debugging info to the console if it is present on the response object

@@ -34,0 +40,0 @@ */

@@ -22,12 +22,24 @@ import { SearchServiceError, SearchServiceErrorType, } from '../search-service-error';

}
const currentUrl = new URL(window.location.href);
const scopeParam = currentUrl.searchParams.get('scope');
const cachingParam = currentUrl.searchParams.get('caching');
const verboseParam = currentUrl.searchParams.get('verbose');
if ((options === null || options === void 0 ? void 0 : options.scope) !== undefined) {
this.requestScope = options.scope;
}
else {
const currentUrl = new URL(window.location.href);
const scope = currentUrl.searchParams.get('scope');
if (scope) {
this.requestScope = scope;
}
else if (scopeParam) {
this.requestScope = scopeParam;
}
if ((options === null || options === void 0 ? void 0 : options.caching) !== undefined) {
this.cachingFlags = options.caching;
}
else if (cachingParam) {
this.cachingFlags = cachingParam;
}
if ((options === null || options === void 0 ? void 0 : options.verbose) !== undefined) {
this.verbose = options.verbose;
}
else if (verboseParam) {
this.verbose = !!verboseParam;
}
}

@@ -45,2 +57,5 @@ /**

}
if (this.cachingFlags) {
finalUrl.searchParams.set('caching', this.cachingFlags);
}
let response;

@@ -65,2 +80,5 @@ // first try the fetch and return a networkError if it fails

const json = await response.json();
if (this.verbose) {
this.printResponse(json);
}
if (json.debugging) {

@@ -95,2 +113,38 @@ this.printDebuggingInfo(json);

/**
* Logs a full response to the console, with truncated hits.
*/
printResponse(json) {
var _a, _b, _c, _d, _e;
try {
const clonedResponse = JSON.parse(JSON.stringify(json));
// Keep at most the first hit, and throw away the rest
const hits = (_c = (_b = (_a = clonedResponse === null || clonedResponse === void 0 ? void 0 : clonedResponse.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.hits) === null || _c === void 0 ? void 0 : _c.hits;
if (Array.isArray(hits) && hits.length > 1) {
const newHits = [];
newHits.push(hits[0]);
newHits.push(`*** ${hits.length - 1} hits omitted ***`);
clonedResponse.response.body.hits.hits = newHits;
}
// Keep the aggregation keys but throw away their buckets
const aggregations = (_e = (_d = clonedResponse === null || clonedResponse === void 0 ? void 0 : clonedResponse.response) === null || _d === void 0 ? void 0 : _d.body) === null || _e === void 0 ? void 0 : _e.aggregations;
if (aggregations) {
Object.entries(aggregations).forEach(([key, val]) => {
var _a, _b, _c, _d;
if (((_b = (_a = val) === null || _a === void 0 ? void 0 : _a.buckets) === null || _b === void 0 ? void 0 : _b.length) > 0) {
const clonedVal = JSON.parse(JSON.stringify(val));
clonedVal.buckets = `*** ${(_d = (_c = clonedVal.buckets) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0} buckets omitted ***`;
clonedResponse.response.body.aggregations[key] = clonedVal;
}
});
}
console.log(`***** RESPONSE RECEIVED *****`);
console.groupCollapsed('Response');
console.log(JSON.stringify(clonedResponse, null, 2));
console.groupEnd();
}
catch (err) {
console.error('Error printing search response:', err);
}
}
/**
* Logs PPS debugging info to the console if it is present on the response object

@@ -97,0 +151,0 @@ */

@@ -10,6 +10,27 @@ /**

baseUrl?: string;
/**
* The path the to the backend service to send requests to, at the base URL.
*/
servicePath?: string;
/**
* Whether to include credentials in the request.
* Only works when not blocked by CORS policy.
*/
includeCredentials?: boolean;
/**
* The request scope to send to the PPS.
*/
scope?: string;
/**
* Optional caching requests to the backend, e.g. to bypass or recompute the cache
*/
caching?: string;
/**
* Whether debugging info should be requested and logged when present on a response
*/
debuggingEnabled?: boolean;
/**
* Whether the full response details should be logged for every response
*/
verbose?: boolean;
}

@@ -46,6 +46,6 @@ import { __decorate } from "tslib";

// We can memoize backends based on their params, to avoid constructing redundant backends
const { includeCredentials = '', scope = '', baseUrl = '' } = options;
return `${type};${includeCredentials};${scope};${baseUrl}`;
const { includeCredentials = false, verbose = false, scope = '', baseUrl = '', } = options;
return `${type};${includeCredentials};${verbose};${scope};${baseUrl}`;
})
], SearchService, "getBackendForSearchType", null);
//# sourceMappingURL=search-service.js.map

@@ -57,2 +57,34 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

});
it('includes scope param from URL if not provided', async () => {
const url = new URL(window.location.href);
url.searchParams.set('scope', 'boop');
window.history.replaceState({}, '', url.toString());
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('scope')).to.equal('boop');
url.searchParams.delete('scope');
window.history.replaceState({}, '', url.toString());
});
it('includes caching param if provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const backend = new FulltextSearchBackend({
caching: cachingParam,
});
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
});
it('includes caching param from URL if not provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const url = new URL(window.location.href);
url.searchParams.set('caching', cachingParam);
window.history.replaceState({}, '', url.toString());
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
url.searchParams.delete('caching');
window.history.replaceState({}, '', url.toString());
});
it('can enable debugging by default on all searches', async () => {

@@ -141,3 +173,69 @@ const backend = new FulltextSearchBackend({

});
it('logs response to console if verbose=true', async () => {
const responseObj = {
response: {
body: {
hits: {
hits: ['h1', 'h2', 'h3', 'h4', 'h5'],
},
aggregations: {
creator: {
buckets: ['c1', 'c2', 'c3', 'c4', 'c5'],
},
},
},
},
};
const expectedLogObj = {
response: {
body: {
hits: {
hits: ['h1', '*** 4 hits omitted ***'],
},
aggregations: {
creator: {
buckets: '*** 5 buckets omitted ***',
},
},
},
},
};
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify(responseObj));
};
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new FulltextSearchBackend({ verbose: true });
await backend.performSearch({
query: 'boop',
});
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
expect(logSpy.args[1][0]).to.equal(JSON.stringify(expectedLogObj, null, 2));
window.fetch = fetchBackup;
console.log = logBackup;
});
it('includes verbose param from URL if not provided', async () => {
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify({}));
};
const url = new URL(window.location.href);
url.searchParams.set('verbose', '1');
window.history.replaceState({}, '', url.toString());
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
window.fetch = fetchBackup;
console.log = logBackup;
url.searchParams.delete('verbose');
window.history.replaceState({}, '', url.toString());
});
});
//# sourceMappingURL=fulltext-search-backend.test.js.map

@@ -57,2 +57,34 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

});
it('includes scope param from URL if not provided', async () => {
const url = new URL(window.location.href);
url.searchParams.set('scope', 'boop');
window.history.replaceState({}, '', url.toString());
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('scope')).to.equal('boop');
url.searchParams.delete('scope');
window.history.replaceState({}, '', url.toString());
});
it('includes caching param if provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const backend = new MetadataSearchBackend({
caching: cachingParam,
});
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
});
it('includes caching param from URL if not provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const url = new URL(window.location.href);
url.searchParams.set('caching', cachingParam);
window.history.replaceState({}, '', url.toString());
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
url.searchParams.delete('caching');
window.history.replaceState({}, '', url.toString());
});
it('can enable debugging by default on all searches', async () => {

@@ -141,3 +173,69 @@ const backend = new MetadataSearchBackend({

});
it('logs response to console if verbose=true', async () => {
const responseObj = {
response: {
body: {
hits: {
hits: ['h1', 'h2', 'h3', 'h4', 'h5'],
},
aggregations: {
creator: {
buckets: ['c1', 'c2', 'c3', 'c4', 'c5'],
},
},
},
},
};
const expectedLogObj = {
response: {
body: {
hits: {
hits: ['h1', '*** 4 hits omitted ***'],
},
aggregations: {
creator: {
buckets: '*** 5 buckets omitted ***',
},
},
},
},
};
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify(responseObj));
};
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new MetadataSearchBackend({ verbose: true });
await backend.performSearch({
query: 'boop',
});
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
expect(logSpy.args[1][0]).to.equal(JSON.stringify(expectedLogObj, null, 2));
window.fetch = fetchBackup;
console.log = logBackup;
});
it('includes verbose param from URL if not provided', async () => {
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify({}));
};
const url = new URL(window.location.href);
url.searchParams.set('verbose', '1');
window.history.replaceState({}, '', url.toString());
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
window.fetch = fetchBackup;
console.log = logBackup;
url.searchParams.delete('verbose');
window.history.replaceState({}, '', url.toString());
});
});
//# sourceMappingURL=metadata-search-backend.test.js.map
{
"name": "@internetarchive/search-service",
"version": "0.4.5",
"version": "0.4.6-alpha.2",
"description": "A search service for the Internet Archive",

@@ -5,0 +5,0 @@ "license": "AGPL-3.0-only",

@@ -23,2 +23,6 @@ import { Memoize } from 'typescript-memoize';

ALPHABETICAL,
/**
* Sort descending numerically by key
*/
NUMERIC,
}

@@ -71,12 +75,18 @@

* @param sortType What to sort the buckets on.
* Accepted values are `AggregationSortType.COUNT` (descending order) and
* `AggregationSortType.ALPHABETICAL` (ascending order).
* Accepted values are:
* - `AggregationSortType.COUNT` (descending order)
* - `AggregationSortType.ALPHABETICAL` (ascending order)
* - `AggregationSortType.NUMERIC` (descending order)
*/
@Memoize()
getSortedBuckets(sortType?: AggregationSortType): Bucket[] | number[] {
// Don't apply sorts to numeric buckets.
const copiedBuckets = [...this.buckets] as Bucket[] | number[];
// Don't apply sorts to number[] aggregations (like year_histogram).
// Note this _doesn't_ apply to ordinary year aggregations, which have
// keyed buckets just like most other facet types.
// Assumption here is that all the buckets have the same type as the
// first bucket (which should be true in principle).
if (typeof this.buckets[0] === 'number') {
return [...(this.buckets as number[])];
if (this.isRawNumberBuckets(copiedBuckets)) {
return copiedBuckets;
}

@@ -89,11 +99,26 @@

case AggregationSortType.ALPHABETICAL:
return [...(this.buckets as Bucket[])].sort((a, b) => {
return copiedBuckets.sort((a, b) => {
return collator.compare(a.key.toString(), b.key.toString());
});
case AggregationSortType.NUMERIC:
return copiedBuckets.sort((a, b) => {
return Number(b.key) - Number(a.key);
});
case AggregationSortType.COUNT:
default:
// Sorted by count by default
return [...(this.buckets as Bucket[])];
return copiedBuckets;
}
}
/**
* Type guard for number[] buckets, since the buckets provided by the PPS
* may be either keyed objects or just an array of numbers. Currently only
* `year_histogram` facets are of the latter type.
*/
private isRawNumberBuckets(
buckets: Bucket[] | number[]
): buckets is number[] {
return typeof this.buckets[0] === 'number';
}
}

@@ -0,0 +0,0 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

@@ -23,2 +23,3 @@ /**

aggregations_size?: number;
uid?: string;
}

@@ -25,2 +25,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

protected cachingFlags?: string;
protected verbose?: boolean;
protected debuggingEnabled?: boolean;

@@ -44,11 +48,24 @@

const currentUrl = new URL(window.location.href);
const scopeParam = currentUrl.searchParams.get('scope');
const cachingParam = currentUrl.searchParams.get('caching');
const verboseParam = currentUrl.searchParams.get('verbose');
if (options?.scope !== undefined) {
this.requestScope = options.scope;
} else {
const currentUrl = new URL(window.location.href);
const scope = currentUrl.searchParams.get('scope');
if (scope) {
this.requestScope = scope;
}
} else if (scopeParam) {
this.requestScope = scopeParam;
}
if (options?.caching !== undefined) {
this.cachingFlags = options.caching;
} else if (cachingParam) {
this.cachingFlags = cachingParam;
}
if (options?.verbose !== undefined) {
this.verbose = options.verbose;
} else if (verboseParam) {
this.verbose = !!verboseParam;
}
}

@@ -77,2 +94,6 @@

if (this.cachingFlags) {
finalUrl.searchParams.set('caching', this.cachingFlags);
}
let response: Response;

@@ -99,2 +120,6 @@ // first try the fetch and return a networkError if it fails

if (this.verbose) {
this.printResponse(json);
}
if (json.debugging) {

@@ -139,2 +164,41 @@ this.printDebuggingInfo(json);

/**
* Logs a full response to the console, with truncated hits.
*/
private printResponse(json: Record<string, any>) {
try {
const clonedResponse = JSON.parse(JSON.stringify(json));
// Keep at most the first hit, and throw away the rest
const hits = clonedResponse?.response?.body?.hits?.hits;
if (Array.isArray(hits) && hits.length > 1) {
const newHits = [];
newHits.push(hits[0]);
newHits.push(`*** ${hits.length - 1} hits omitted ***`);
clonedResponse.response.body.hits.hits = newHits;
}
// Keep the aggregation keys but throw away their buckets
const aggregations = clonedResponse?.response?.body?.aggregations;
if (aggregations) {
Object.entries(aggregations).forEach(([key, val]) => {
if ((val as any)?.buckets?.length > 0) {
const clonedVal = JSON.parse(JSON.stringify(val));
clonedVal.buckets = `*** ${
clonedVal.buckets?.length ?? 0
} buckets omitted ***`;
clonedResponse.response.body.aggregations[key] = clonedVal;
}
});
}
console.log(`***** RESPONSE RECEIVED *****`);
console.groupCollapsed('Response');
console.log(JSON.stringify(clonedResponse, null, 2));
console.groupEnd();
} catch (err) {
console.error('Error printing search response:', err);
}
}
/**
* Logs PPS debugging info to the console if it is present on the response object

@@ -141,0 +205,0 @@ */

@@ -10,6 +10,33 @@ /**

baseUrl?: string;
/**
* The path the to the backend service to send requests to, at the base URL.
*/
servicePath?: string;
/**
* Whether to include credentials in the request.
* Only works when not blocked by CORS policy.
*/
includeCredentials?: boolean;
/**
* The request scope to send to the PPS.
*/
scope?: string;
/**
* Optional caching requests to the backend, e.g. to bypass or recompute the cache
*/
caching?: string;
/**
* Whether debugging info should be requested and logged when present on a response
*/
debuggingEnabled?: boolean;
/**
* Whether the full response details should be logged for every response
*/
verbose?: boolean;
}

@@ -52,4 +52,9 @@ import { SearchResponse } from './responses/search-response';

// We can memoize backends based on their params, to avoid constructing redundant backends
const { includeCredentials = '', scope = '', baseUrl = '' } = options;
return `${type};${includeCredentials};${scope};${baseUrl}`;
const {
includeCredentials = false,
verbose = false,
scope = '',
baseUrl = '',
} = options;
return `${type};${includeCredentials};${verbose};${scope};${baseUrl}`;
})

@@ -56,0 +61,0 @@ static getBackendForSearchType(

@@ -0,0 +0,0 @@ import { DateParser } from '@internetarchive/field-parsers';

@@ -78,2 +78,45 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

it('includes scope param from URL if not provided', async () => {
const url = new URL(window.location.href);
url.searchParams.set('scope', 'boop');
window.history.replaceState({}, '', url.toString());
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('scope')).to.equal('boop');
url.searchParams.delete('scope');
window.history.replaceState({}, '', url.toString());
});
it('includes caching param if provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const backend = new FulltextSearchBackend({
caching: cachingParam,
});
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
});
it('includes caching param from URL if not provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const url = new URL(window.location.href);
url.searchParams.set('caching', cachingParam);
window.history.replaceState({}, '', url.toString());
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
url.searchParams.delete('caching');
window.history.replaceState({}, '', url.toString());
});
it('can enable debugging by default on all searches', async () => {

@@ -179,2 +222,81 @@ const backend = new FulltextSearchBackend({

});
it('logs response to console if verbose=true', async () => {
const responseObj = {
response: {
body: {
hits: {
hits: ['h1', 'h2', 'h3', 'h4', 'h5'],
},
aggregations: {
creator: {
buckets: ['c1', 'c2', 'c3', 'c4', 'c5'],
},
},
},
},
};
const expectedLogObj = {
response: {
body: {
hits: {
hits: ['h1', '*** 4 hits omitted ***'],
},
aggregations: {
creator: {
buckets: '*** 5 buckets omitted ***',
},
},
},
},
};
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify(responseObj));
};
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new FulltextSearchBackend({ verbose: true });
await backend.performSearch({
query: 'boop',
});
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
expect(logSpy.args[1][0]).to.equal(JSON.stringify(expectedLogObj, null, 2));
window.fetch = fetchBackup;
console.log = logBackup;
});
it('includes verbose param from URL if not provided', async () => {
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify({}));
};
const url = new URL(window.location.href);
url.searchParams.set('verbose', '1');
window.history.replaceState({}, '', url.toString());
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new FulltextSearchBackend();
await backend.performSearch({ query: 'foo' });
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
window.fetch = fetchBackup;
console.log = logBackup;
url.searchParams.delete('verbose');
window.history.replaceState({}, '', url.toString());
});
});

@@ -78,2 +78,45 @@ /* eslint-disable @typescript-eslint/no-unused-vars */

it('includes scope param from URL if not provided', async () => {
const url = new URL(window.location.href);
url.searchParams.set('scope', 'boop');
window.history.replaceState({}, '', url.toString());
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('scope')).to.equal('boop');
url.searchParams.delete('scope');
window.history.replaceState({}, '', url.toString());
});
it('includes caching param if provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const backend = new MetadataSearchBackend({
caching: cachingParam,
});
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
});
it('includes caching param from URL if not provided', async () => {
const cachingParam = JSON.stringify({ bypass: true });
const url = new URL(window.location.href);
url.searchParams.set('caching', cachingParam);
window.history.replaceState({}, '', url.toString());
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
const queryParams = new URL(urlCalled!.toString()).searchParams;
expect(queryParams.get('caching')).to.equal(cachingParam);
url.searchParams.delete('caching');
window.history.replaceState({}, '', url.toString());
});
it('can enable debugging by default on all searches', async () => {

@@ -179,2 +222,81 @@ const backend = new MetadataSearchBackend({

});
it('logs response to console if verbose=true', async () => {
const responseObj = {
response: {
body: {
hits: {
hits: ['h1', 'h2', 'h3', 'h4', 'h5'],
},
aggregations: {
creator: {
buckets: ['c1', 'c2', 'c3', 'c4', 'c5'],
},
},
},
},
};
const expectedLogObj = {
response: {
body: {
hits: {
hits: ['h1', '*** 4 hits omitted ***'],
},
aggregations: {
creator: {
buckets: '*** 5 buckets omitted ***',
},
},
},
},
};
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify(responseObj));
};
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new MetadataSearchBackend({ verbose: true });
await backend.performSearch({
query: 'boop',
});
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
expect(logSpy.args[1][0]).to.equal(JSON.stringify(expectedLogObj, null, 2));
window.fetch = fetchBackup;
console.log = logBackup;
});
it('includes verbose param from URL if not provided', async () => {
const fetchBackup = window.fetch;
window.fetch = async () => {
return new Response(JSON.stringify({}));
};
const url = new URL(window.location.href);
url.searchParams.set('verbose', '1');
window.history.replaceState({}, '', url.toString());
const logBackup = console.log;
const logSpy = Sinon.spy();
console.log = logSpy;
const backend = new MetadataSearchBackend();
await backend.performSearch({ query: 'foo' });
expect(logSpy.callCount).to.be.greaterThan(0);
expect(logSpy.args[0][0]).to.equal('***** RESPONSE RECEIVED *****');
window.fetch = fetchBackup;
console.log = logBackup;
url.searchParams.delete('verbose');
window.history.replaceState({}, '', url.toString());
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc