Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@internetarchive/search-service

Package Overview
Dependencies
Maintainers
18
Versions
157
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 1.2.5-alpha.24 to 1.2.5-alpha.25

6

dist/src/models/hit-types/hit.d.ts

@@ -20,2 +20,6 @@ import type { ItemHit } from './item-hit';

/**
* Type that includes all the fields present on any type of hit
*/
declare type AllHitFields = ItemHit & TextHit & FavoritedSearchHit & WebArchiveHit;
/**
* Result is an expansive type definition encompassing all the optional

@@ -26,3 +30,3 @@ * and required properties that may occur on any type of search result

*/
export declare type SearchResult = Partial<ItemHit & TextHit & FavoritedSearchHit & WebArchiveHit> & HitInfo;
export declare type SearchResult = Partial<AllHitFields> & HitInfo;
export {};

6

dist/src/responses/page-elements.d.ts

@@ -48,7 +48,3 @@ import { Aggregation } from '../models/aggregation';

export declare type LendingSubElement = typeof LENDING_SUB_ELEMENTS[number];
export interface LendingPageElement extends Record<LendingSubElement, Record<string, unknown>[]> {
loans: Record<string, unknown>[];
waitlist: Record<string, unknown>[];
loan_history: Record<string, unknown>[];
}
export declare type LendingPageElement = Record<LendingSubElement, Record<string, unknown>[]>;
export declare type WebArchivesPageElement = WebArchiveEntry[];

@@ -55,0 +51,0 @@ export declare type ForumPostsPageElement = ForumPost[];

@@ -10,3 +10,9 @@ export const LENDING_SUB_ELEMENTS = [

function fixWebCaptureDateFormatting(date) {
return `${date.slice(0, 4)}-${date.slice(4, 6)}-${date.slice(6, 8)}T${date.slice(8, 10)}:${date.slice(10, 12)}:${date.slice(12, 14)}Z`;
const year = date.slice(0, 4);
const month = date.slice(4, 6);
const day = date.slice(6, 8);
const hour = date.slice(8, 10);
const minute = date.slice(10, 12);
const second = date.slice(12, 14);
return `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;
}

@@ -22,2 +28,4 @@ /**

continue;
const encodedUrl = encodeURIComponent(entry.url);
const href = `https://web.archive.org/web/${entry.captures[0]}/${encodedUrl}`;
results.push({

@@ -28,3 +36,3 @@ hit_type: 'web_archive',

capture_dates: entry.captures.map(date => fixWebCaptureDateFormatting(date)),
__href__: `https://web.archive.org/web/${entry.captures[0]}/${encodeURIComponent(entry.url)}`,
__href__: href,
},

@@ -31,0 +39,0 @@ });

@@ -69,2 +69,12 @@ import { Aggregation } from '../models/aggregation';

/**
* Special handling for when the 'lending' page element is present on the response.
* @returns An array of raw hits representing current loans.
*/
private handleLendingPageElement;
/**
* Special handling for when the 'web_archives' page element is present on the response.
* @returns An array of raw hits representing the web archive results.
*/
private handleWebArchivesPageElement;
/**
* Returns a correctly-typed search result depending on the schema's hit_type.

@@ -71,0 +81,0 @@ */

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

import { FavoritedSearchHit } from '../models/hit-types/favorited-search-hit';
import { WebArchiveHit } from '../models/hit-types/web-archive-hit';
import { convertWebArchivesToSearchHits, LENDING_SUB_ELEMENTS, } from './page-elements';
import { WebArchiveHit } from '../models/hit-types/web-archive-hit';
/**

@@ -17,3 +17,3 @@ * This is the search response details inside the SearchResponse object that contains

constructor(body, schema) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
this.schema = schema;

@@ -36,19 +36,10 @@ const schemaHitType = schema === null || schema === void 0 ? void 0 : schema.hit_type;

}
else if ((_j = this.pageElements) === null || _j === void 0 ? void 0 : _j['lending']) {
const pageElements = this.pageElements['lending'];
hits = (_k = pageElements['loans']) !== null && _k !== void 0 ? _k : [];
this.totalResults = (_l = hits.length) !== null && _l !== void 0 ? _l : 0;
this.returnedCount = this.totalResults;
// For loans, we also need to build hit models for each sub-element
for (const subElement of LENDING_SUB_ELEMENTS) {
pageElements[subElement] = ((_m = pageElements[subElement].map((hit) => { var _a; return SearchResponseDetails.createResult((_a = hit.hit_type) !== null && _a !== void 0 ? _a : schemaHitType, hit); })) !== null && _m !== void 0 ? _m : []);
}
else if ((_j = this.pageElements) === null || _j === void 0 ? void 0 : _j.lending) {
hits = this.handleLendingPageElement(schemaHitType);
}
else if ((_o = this.pageElements) === null || _o === void 0 ? void 0 : _o['web_archives']) {
hits = convertWebArchivesToSearchHits(this.pageElements['web_archives']);
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
else if ((_k = this.pageElements) === null || _k === void 0 ? void 0 : _k.web_archives) {
hits = this.handleWebArchivesPageElement();
}
this.results =
(_p = hits === null || hits === void 0 ? void 0 : hits.map((hit) => { var _a; return SearchResponseDetails.createResult((_a = hit.hit_type) !== null && _a !== void 0 ? _a : schemaHitType, hit); })) !== null && _p !== void 0 ? _p : [];
(_l = hits === null || hits === void 0 ? void 0 : hits.map((hit) => { var _a; return SearchResponseDetails.createResult((_a = hit.hit_type) !== null && _a !== void 0 ? _a : schemaHitType, hit); })) !== null && _l !== void 0 ? _l : [];
// Use aggregations directly from the body if available.

@@ -69,12 +60,39 @@ // Otherwise, try extracting them from the first page_element.

if (body === null || body === void 0 ? void 0 : body.collection_titles) {
this.collectionTitles = (_q = body.collection_titles) !== null && _q !== void 0 ? _q : {};
this.collectionTitles = (_m = body.collection_titles) !== null && _m !== void 0 ? _m : {};
}
if (body === null || body === void 0 ? void 0 : body.collection_extra_info) {
this.collectionExtraInfo = (_r = body.collection_extra_info) !== null && _r !== void 0 ? _r : null;
this.collectionExtraInfo = (_o = body.collection_extra_info) !== null && _o !== void 0 ? _o : null;
}
if (body === null || body === void 0 ? void 0 : body.account_extra_info) {
this.accountExtraInfo = (_s = body.account_extra_info) !== null && _s !== void 0 ? _s : null;
this.accountExtraInfo = (_p = body.account_extra_info) !== null && _p !== void 0 ? _p : null;
}
}
/**
* Special handling for when the 'lending' page element is present on the response.
* @returns An array of raw hits representing current loans.
*/
handleLendingPageElement(schemaHitType) {
var _a, _b, _c;
const pageElements = (_a = this.pageElements) === null || _a === void 0 ? void 0 : _a.lending;
const hits = (_b = pageElements.loans) !== null && _b !== void 0 ? _b : [];
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
// For loans, we also need to build hit models for each sub-element
for (const subElement of LENDING_SUB_ELEMENTS) {
pageElements[subElement] = ((_c = pageElements[subElement].map((hit) => { var _a; return SearchResponseDetails.createResult((_a = hit.hit_type) !== null && _a !== void 0 ? _a : schemaHitType, hit); })) !== null && _c !== void 0 ? _c : []);
}
return hits;
}
/**
* Special handling for when the 'web_archives' page element is present on the response.
* @returns An array of raw hits representing the web archive results.
*/
handleWebArchivesPageElement() {
var _a;
const hits = convertWebArchivesToSearchHits((_a = this.pageElements) === null || _a === void 0 ? void 0 : _a.web_archives);
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
return hits;
}
/**
* Returns a correctly-typed search result depending on the schema's hit_type.

@@ -81,0 +99,0 @@ */

@@ -6,2 +6,15 @@ import { expect } from '@open-wc/testing';

import { SearchResponseDetails, } from '../../src/responses/search-response-details';
import { FavoritedSearchHit } from '../../src/models/hit-types/favorited-search-hit';
const itemSchema = {
hit_type: 'item',
field_properties: {},
};
const textSchema = {
hit_type: 'text',
field_properties: {},
};
const favSearchSchema = {
hit_type: 'favorited_search',
field_properties: {},
};
const responseBody = {

@@ -33,10 +46,147 @@ hits: {

};
const favSearchResponseBody = {
hits: {
total: 1,
returned: 1,
hits: [
{
hit_type: 'favorited_search',
fields: {
query: 'foo',
mediatype: 'search',
title: 'Foo',
},
},
],
},
};
const accountUploadsResponseBody = {
page_elements: {
uploads: {
hits: {
total: 2,
returned: 2,
hits: [
{
hit_type: 'item',
fields: {
identifier: 'foo',
mediatype: 'texts',
},
},
{
hit_type: 'item',
fields: {
identifier: 'bar',
collection: ['baz'],
},
},
],
},
aggregations: {
subject: new Aggregation({
buckets: [{ key: 'foo', doc_count: 1 }],
}),
},
},
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
const accountLendingResponseBody = {
page_elements: {
lending: {
loans: [
{
fields: {
identifier: 'foo',
mediatype: 'texts',
},
},
],
waitlist: [
{
hit_type: 'item',
fields: {
identifier: 'bar',
mediatype: 'texts',
},
},
],
loan_history: [
{
hit_type: 'item',
fields: {
identifier: 'baz',
mediatype: 'texts',
},
},
],
},
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
const accountWebArchivesResponseBody = {
page_elements: {
web_archives: [
{
url: 'https://example.com/',
captures: ['20100102030405', '20110203040506'],
},
{
url: 'https://web.archive.org/save/',
captures: [], // This one will be skipped due to empty captures
},
],
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
describe('SearchResponseDetails', () => {
it('constructs item hits', () => {
var _a, _b, _c;
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results[0]).to.be.instanceOf(ItemHit);

@@ -51,7 +201,3 @@ expect(details.results[0].identifier).to.equal('foo');

var _a, _b, _c;
const responseSchema = {
hit_type: 'text',
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, textSchema);
expect(details.results[0]).to.be.instanceOf(TextHit);

@@ -64,2 +210,9 @@ expect(details.results[0].identifier).to.equal('foo');

});
it('constructs favorited search hits', () => {
var _a, _b;
const details = new SearchResponseDetails(favSearchResponseBody, favSearchSchema);
expect(details.results[0]).to.be.instanceOf(FavoritedSearchHit);
expect((_a = details.results[0].query) === null || _a === void 0 ? void 0 : _a.value).to.equal('foo');
expect((_b = details.results[0].title) === null || _b === void 0 ? void 0 : _b.value).to.equal('Foo');
});
it('prefers hit-type specified on hit itself over schema hit-type', () => {

@@ -87,7 +240,3 @@ var _a, _b, _c;

};
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBodyWithTextHit, responseSchema);
const details = new SearchResponseDetails(responseBodyWithTextHit, itemSchema);
expect(details.results[0]).to.be.instanceOf(TextHit); // From hit, not schema

@@ -101,2 +250,7 @@ expect(details.results[0].identifier).to.equal('foo');

});
it('constructs item hits when hit type unspecified', () => {
const details = new SearchResponseDetails(responseBody, {});
expect(details.results[0]).to.be.instanceOf(ItemHit);
expect(details.results[0].identifier).to.equal('foo');
});
it('includes aggregations', () => {

@@ -120,7 +274,3 @@ const aggsResponseBody = {

};
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(aggsResponseBody, responseSchema);
const details = new SearchResponseDetails(aggsResponseBody, itemSchema);
expect(details.results.length).to.equal(0);

@@ -139,7 +289,3 @@ expect(details.aggregations).to.deep.equal({

it('provides access to collection titles map', () => {
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results.length).to.equal(2);

@@ -151,7 +297,3 @@ expect(details.collectionTitles).to.deep.equal({ baz: 'Baz Collection' });

delete responseBodyWithoutTitles.collection_titles;
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBodyWithoutTitles, responseSchema);
const details = new SearchResponseDetails(responseBodyWithoutTitles, itemSchema);
expect(details.results.length).to.equal(2);

@@ -161,7 +303,3 @@ expect(details.collectionTitles).to.be.undefined;

it('provides access to collection extra info', () => {
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results.length).to.equal(2);

@@ -175,11 +313,56 @@ expect(details.collectionExtraInfo).to.deep.equal({ thumbnail_url: 'foo' });

delete responseBodyWithoutExtraInfo.collection_extra_info;
const responseSchema = {
hit_type: 'item',
field_properties: {},
};
const details = new SearchResponseDetails(responseBodyWithoutExtraInfo, responseSchema);
const details = new SearchResponseDetails(responseBodyWithoutExtraInfo, itemSchema);
expect(details.results.length).to.equal(2);
expect(details.collectionExtraInfo).to.be.undefined;
});
it('provides access to account extra info', () => {
var _a, _b;
const details = new SearchResponseDetails(accountUploadsResponseBody, itemSchema);
expect((_b = (_a = details.accountExtraInfo) === null || _a === void 0 ? void 0 : _a.user_item_metadata) === null || _b === void 0 ? void 0 : _b.description).to.equal('Foo bar baz');
});
it('account extra info is optional', () => {
const accountBodyWithoutExtraInfo = {
...accountUploadsResponseBody,
};
delete accountBodyWithoutExtraInfo.account_extra_info;
const details = new SearchResponseDetails(accountBodyWithoutExtraInfo, itemSchema);
expect(details.results.length).to.equal(2);
expect(details.accountExtraInfo).to.be.undefined;
});
it('provides access to hits from page element', () => {
const details = new SearchResponseDetails(accountUploadsResponseBody, itemSchema);
expect(details.results.length).to.equal(2);
expect(details.results[0].identifier).to.equal('foo');
});
it('provides access to aggregations from page element', () => {
var _a, _b;
const details = new SearchResponseDetails(accountUploadsResponseBody, itemSchema);
expect(details.aggregations).to.exist;
expect((_b = (_a = details.aggregations) === null || _a === void 0 ? void 0 : _a.subject) === null || _b === void 0 ? void 0 : _b.buckets[0]).to.deep.equal({
key: 'foo',
doc_count: 1,
});
});
it('provides access to lending page elements', () => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
const details = new SearchResponseDetails(accountLendingResponseBody, itemSchema);
expect(details.results.length, 'results length').to.equal(1);
expect(details.totalResults, 'total').to.equal(1);
expect(details.returnedCount, 'returned').to.equal(1);
expect((_d = (_c = (_b = (_a = details.pageElements) === null || _a === void 0 ? void 0 : _a.lending) === null || _b === void 0 ? void 0 : _b.loans) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.identifier).to.equal('foo');
expect((_h = (_g = (_f = (_e = details.pageElements) === null || _e === void 0 ? void 0 : _e.lending) === null || _f === void 0 ? void 0 : _f.waitlist) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.identifier).to.equal('bar');
expect((_m = (_l = (_k = (_j = details.pageElements) === null || _j === void 0 ? void 0 : _j.lending) === null || _k === void 0 ? void 0 : _k.loan_history) === null || _l === void 0 ? void 0 : _l[0]) === null || _m === void 0 ? void 0 : _m.identifier).to.equal('baz');
});
it('provides access to web archive page elements', () => {
var _a, _b, _c, _d;
const details = new SearchResponseDetails(accountWebArchivesResponseBody, itemSchema);
expect(details.results.length, 'results length').to.equal(1);
expect(details.totalResults, 'total').to.equal(1);
expect(details.returnedCount, 'returned').to.equal(1);
const webArchiveResult = details.results[0];
expect((_a = webArchiveResult.title) === null || _a === void 0 ? void 0 : _a.value).to.equal('https://example.com/');
expect((_c = (_b = webArchiveResult.capture_dates) === null || _b === void 0 ? void 0 : _b.values) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
expect((_d = webArchiveResult.__href__) === null || _d === void 0 ? void 0 : _d.value).to.equal('https://web.archive.org/web/20100102030405/https%3A%2F%2Fexample.com%2F');
});
});
//# sourceMappingURL=search-response-details.test.js.map
{
"name": "@internetarchive/search-service",
"version": "1.2.5-alpha.24",
"version": "1.2.5-alpha.25",
"description": "A search service for the Internet Archive",

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

@@ -23,2 +23,7 @@ import type { ItemHit } from './item-hit';

/**
* Type that includes all the fields present on any type of hit
*/
type AllHitFields = ItemHit & TextHit & FavoritedSearchHit & WebArchiveHit;
/**
* Result is an expansive type definition encompassing all the optional

@@ -29,5 +34,2 @@ * and required properties that may occur on any type of search result

*/
export type SearchResult = Partial<
ItemHit & TextHit & FavoritedSearchHit & WebArchiveHit
> &
HitInfo;
export type SearchResult = Partial<AllHitFields> & HitInfo;

@@ -65,8 +65,6 @@ import { Aggregation } from '../models/aggregation';

export type LendingSubElement = typeof LENDING_SUB_ELEMENTS[number];
export interface LendingPageElement
extends Record<LendingSubElement, Record<string, unknown>[]> {
loans: Record<string, unknown>[];
waitlist: Record<string, unknown>[];
loan_history: Record<string, unknown>[];
}
export type LendingPageElement = Record<
LendingSubElement,
Record<string, unknown>[]
>;

@@ -102,6 +100,9 @@ export type WebArchivesPageElement = WebArchiveEntry[];

function fixWebCaptureDateFormatting(date: string): string {
return `${date.slice(0, 4)}-${date.slice(4, 6)}-${date.slice(
6,
8
)}T${date.slice(8, 10)}:${date.slice(10, 12)}:${date.slice(12, 14)}Z`;
const year = date.slice(0, 4);
const month = date.slice(4, 6);
const day = date.slice(6, 8);
const hour = date.slice(8, 10);
const minute = date.slice(10, 12);
const second = date.slice(12, 14);
return `${year}-${month}-${day}T${hour}:${minute}:${second}Z`;
}

@@ -120,2 +121,4 @@

const encodedUrl = encodeURIComponent(entry.url);
const href = `https://web.archive.org/web/${entry.captures[0]}/${encodedUrl}`;
results.push({

@@ -128,5 +131,3 @@ hit_type: 'web_archive',

),
__href__: `https://web.archive.org/web/${
entry.captures[0]
}/${encodeURIComponent(entry.url)}`,
__href__: href,
},

@@ -133,0 +134,0 @@ });

@@ -7,2 +7,3 @@ /* eslint-disable @typescript-eslint/no-explicit-any */

import { FavoritedSearchHit } from '../models/hit-types/favorited-search-hit';
import { WebArchiveHit } from '../models/hit-types/web-archive-hit';
import { CollectionExtraInfo } from './collection-extra-info';

@@ -17,4 +18,4 @@ import type { SearchHitSchema } from './search-hit-schema';

LENDING_SUB_ELEMENTS,
WebArchivesPageElement,
} from './page-elements';
import { WebArchiveHit } from '../models/hit-types/web-archive-hit';

@@ -111,20 +112,6 @@ /**

this.returnedCount = firstPageElement.hits.returned ?? 0;
} else if (this.pageElements?.['lending']) {
const pageElements = this.pageElements['lending'] as LendingPageElement;
hits = pageElements['loans'] ?? [];
this.totalResults = hits.length ?? 0;
this.returnedCount = this.totalResults;
// For loans, we also need to build hit models for each sub-element
for (const subElement of LENDING_SUB_ELEMENTS) {
pageElements[subElement] = (pageElements[
subElement
].map((hit: SearchResult) =>
SearchResponseDetails.createResult(hit.hit_type ?? schemaHitType, hit)
) ?? []) as Record<string, unknown>[];
}
} else if (this.pageElements?.['web_archives']) {
hits = convertWebArchivesToSearchHits(this.pageElements['web_archives']);
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
} else if (this.pageElements?.lending) {
hits = this.handleLendingPageElement(schemaHitType);
} else if (this.pageElements?.web_archives) {
hits = this.handleWebArchivesPageElement();
}

@@ -172,2 +159,39 @@

/**
* Special handling for when the 'lending' page element is present on the response.
* @returns An array of raw hits representing current loans.
*/
private handleLendingPageElement(
schemaHitType: HitType
): Record<string, unknown>[] {
const pageElements = this.pageElements?.lending as LendingPageElement;
const hits = pageElements.loans ?? [];
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
// For loans, we also need to build hit models for each sub-element
for (const subElement of LENDING_SUB_ELEMENTS) {
pageElements[subElement] = (pageElements[
subElement
].map((hit: SearchResult) =>
SearchResponseDetails.createResult(hit.hit_type ?? schemaHitType, hit)
) ?? []) as Record<string, unknown>[];
}
return hits;
}
/**
* Special handling for when the 'web_archives' page element is present on the response.
* @returns An array of raw hits representing the web archive results.
*/
private handleWebArchivesPageElement(): Record<string, unknown>[] {
const hits = convertWebArchivesToSearchHits(
this.pageElements?.web_archives as WebArchivesPageElement
);
this.totalResults = hits.length;
this.returnedCount = this.totalResults;
return hits;
}
/**
* Returns a correctly-typed search result depending on the schema's hit_type.

@@ -174,0 +198,0 @@ */

@@ -10,3 +10,20 @@ import { expect } from '@open-wc/testing';

} from '../../src/responses/search-response-details';
import { SearchHitSchema } from '../../src/responses/search-hit-schema';
import { FavoritedSearchHit } from '../../src/models/hit-types/favorited-search-hit';
const itemSchema: SearchHitSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const textSchema: SearchHitSchema = {
hit_type: 'text' as HitType,
field_properties: {},
};
const favSearchSchema: SearchHitSchema = {
hit_type: 'favorited_search' as HitType,
field_properties: {},
};
const responseBody: SearchResponseBody = {

@@ -39,10 +56,150 @@ hits: {

const favSearchResponseBody: SearchResponseBody = {
hits: {
total: 1,
returned: 1,
hits: [
{
hit_type: 'favorited_search',
fields: {
query: 'foo',
mediatype: 'search',
title: 'Foo',
},
},
],
},
};
const accountUploadsResponseBody: SearchResponseBody = {
page_elements: {
uploads: {
hits: {
total: 2,
returned: 2,
hits: [
{
hit_type: 'item',
fields: {
identifier: 'foo',
mediatype: 'texts',
},
},
{
hit_type: 'item',
fields: {
identifier: 'bar',
collection: ['baz'],
},
},
],
},
aggregations: {
subject: new Aggregation({
buckets: [{ key: 'foo', doc_count: 1 }],
}),
},
},
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
const accountLendingResponseBody: SearchResponseBody = {
page_elements: {
lending: {
loans: [
{
fields: {
identifier: 'foo',
mediatype: 'texts',
},
},
],
waitlist: [
{
hit_type: 'item',
fields: {
identifier: 'bar',
mediatype: 'texts',
},
},
],
loan_history: [
{
hit_type: 'item',
fields: {
identifier: 'baz',
mediatype: 'texts',
},
},
],
},
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
const accountWebArchivesResponseBody: SearchResponseBody = {
page_elements: {
web_archives: [
{
url: 'https://example.com/',
captures: ['20100102030405', '20110203040506'],
},
{
url: 'https://web.archive.org/save/',
captures: [], // This one will be skipped due to empty captures
},
],
},
account_extra_info: {
account_details: {
screenname: 'Foobar',
user_item_identifier: '@foobar',
user_since: '2010-01-02T03:04:05Z',
},
policy_settings: {
is_archive_user: true,
preferences: [],
privileges: [],
},
user_item_metadata: {
title: 'Foobar',
description: 'Foo bar baz',
},
},
};
describe('SearchResponseDetails', () => {
it('constructs item hits', () => {
const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results[0]).to.be.instanceOf(ItemHit);

@@ -57,8 +214,3 @@ expect(details.results[0].identifier).to.equal('foo');

it('constructs text hits', () => {
const responseSchema = {
hit_type: 'text' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, textSchema);
expect(details.results[0]).to.be.instanceOf(TextHit);

@@ -72,2 +224,12 @@ expect(details.results[0].identifier).to.equal('foo');

it('constructs favorited search hits', () => {
const details = new SearchResponseDetails(
favSearchResponseBody,
favSearchSchema
);
expect(details.results[0]).to.be.instanceOf(FavoritedSearchHit);
expect(details.results[0].query?.value).to.equal('foo');
expect(details.results[0].title?.value).to.equal('Foo');
});
it('prefers hit-type specified on hit itself over schema hit-type', () => {

@@ -95,10 +257,5 @@ const responseBodyWithTextHit = { ...responseBody } as SearchResponseBody;

const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(
responseBodyWithTextHit,
responseSchema
itemSchema
);

@@ -114,2 +271,11 @@ expect(details.results[0]).to.be.instanceOf(TextHit); // From hit, not schema

it('constructs item hits when hit type unspecified', () => {
const details = new SearchResponseDetails(
responseBody,
{} as SearchHitSchema
);
expect(details.results[0]).to.be.instanceOf(ItemHit);
expect(details.results[0].identifier).to.equal('foo');
});
it('includes aggregations', () => {

@@ -134,8 +300,3 @@ const aggsResponseBody: SearchResponseBody = {

const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(aggsResponseBody, responseSchema);
const details = new SearchResponseDetails(aggsResponseBody, itemSchema);
expect(details.results.length).to.equal(0);

@@ -155,8 +316,3 @@ expect(details.aggregations).to.deep.equal({

it('provides access to collection titles map', () => {
const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results.length).to.equal(2);

@@ -170,10 +326,5 @@ expect(details.collectionTitles).to.deep.equal({ baz: 'Baz Collection' });

const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(
responseBodyWithoutTitles,
responseSchema
itemSchema
);

@@ -185,8 +336,3 @@ expect(details.results.length).to.equal(2);

it('provides access to collection extra info', () => {
const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(responseBody, responseSchema);
const details = new SearchResponseDetails(responseBody, itemSchema);
expect(details.results.length).to.equal(2);

@@ -202,10 +348,5 @@ expect(details.collectionExtraInfo).to.deep.equal({ thumbnail_url: 'foo' });

const responseSchema = {
hit_type: 'item' as HitType,
field_properties: {},
};
const details = new SearchResponseDetails(
responseBodyWithoutExtraInfo,
responseSchema
itemSchema
);

@@ -215,2 +356,84 @@ expect(details.results.length).to.equal(2);

});
it('provides access to account extra info', () => {
const details = new SearchResponseDetails(
accountUploadsResponseBody,
itemSchema
);
expect(details.accountExtraInfo?.user_item_metadata?.description).to.equal(
'Foo bar baz'
);
});
it('account extra info is optional', () => {
const accountBodyWithoutExtraInfo = {
...accountUploadsResponseBody,
} as SearchResponseBody;
delete accountBodyWithoutExtraInfo.account_extra_info;
const details = new SearchResponseDetails(
accountBodyWithoutExtraInfo,
itemSchema
);
expect(details.results.length).to.equal(2);
expect(details.accountExtraInfo).to.be.undefined;
});
it('provides access to hits from page element', () => {
const details = new SearchResponseDetails(
accountUploadsResponseBody,
itemSchema
);
expect(details.results.length).to.equal(2);
expect(details.results[0].identifier).to.equal('foo');
});
it('provides access to aggregations from page element', () => {
const details = new SearchResponseDetails(
accountUploadsResponseBody,
itemSchema
);
expect(details.aggregations).to.exist;
expect(details.aggregations?.subject?.buckets[0]).to.deep.equal({
key: 'foo',
doc_count: 1,
});
});
it('provides access to lending page elements', () => {
const details = new SearchResponseDetails(
accountLendingResponseBody,
itemSchema
);
expect(details.results.length, 'results length').to.equal(1);
expect(details.totalResults, 'total').to.equal(1);
expect(details.returnedCount, 'returned').to.equal(1);
expect(details.pageElements?.lending?.loans?.[0]?.identifier).to.equal(
'foo'
);
expect(details.pageElements?.lending?.waitlist?.[0]?.identifier).to.equal(
'bar'
);
expect(
details.pageElements?.lending?.loan_history?.[0]?.identifier
).to.equal('baz');
});
it('provides access to web archive page elements', () => {
const details = new SearchResponseDetails(
accountWebArchivesResponseBody,
itemSchema
);
expect(details.results.length, 'results length').to.equal(1);
expect(details.totalResults, 'total').to.equal(1);
expect(details.returnedCount, 'returned').to.equal(1);
const webArchiveResult = details.results[0];
expect(webArchiveResult.title?.value).to.equal('https://example.com/');
expect(webArchiveResult.capture_dates?.values?.length).to.equal(2);
expect(webArchiveResult.__href__?.value).to.equal(
'https://web.archive.org/web/20100102030405/https%3A%2F%2Fexample.com%2F'
);
});
});

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