@internetarchive/search-service
Advanced tools
Comparing version 0.1.2 to 0.1.3-alpha.1
@@ -12,5 +12,5 @@ import { SearchBackendInterface } from './search-backend-interface'; | ||
performSearch(params: SearchParams): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata(identifier: string): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata(identifier: string, keypath?: string): Promise<Result<any, SearchServiceError>>; | ||
private fetchUrl; | ||
private getErrorResult; | ||
} |
@@ -15,4 +15,5 @@ import { SearchServiceError, SearchServiceErrorType, } from '../search-service-error'; | ||
} | ||
async fetchMetadata(identifier) { | ||
const url = `https://${this.baseUrl}/metadata/${identifier}`; | ||
async fetchMetadata(identifier, keypath) { | ||
const path = keypath ? `/${keypath}` : ''; | ||
const url = `https://${this.baseUrl}/metadata/${identifier}${path}`; | ||
return this.fetchUrl(url); | ||
@@ -27,3 +28,7 @@ } | ||
catch (err) { | ||
const message = err instanceof Error ? err.message : err; | ||
const message = err instanceof Error | ||
? err.message | ||
: typeof err === 'string' | ||
? err | ||
: 'Unknown error'; | ||
return this.getErrorResult(SearchServiceErrorType.networkError, message); | ||
@@ -47,3 +52,7 @@ } | ||
catch (err) { | ||
const message = err instanceof Error ? err.message : err; | ||
const message = err instanceof Error | ||
? err.message | ||
: typeof err === 'string' | ||
? err | ||
: 'Unknown error'; | ||
return this.getErrorResult(SearchServiceErrorType.decodingError, message); | ||
@@ -50,0 +59,0 @@ } |
@@ -19,3 +19,3 @@ import { Result } from '@internetarchive/result-type'; | ||
performSearch(params: SearchParams): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata(identifier: string): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata(identifier: string, keypath?: string): Promise<Result<any, SearchServiceError>>; | ||
} |
@@ -23,2 +23,34 @@ import { MetadataResponse } from './responses/metadata/metadata-response'; | ||
fetchMetadata(identifier: string): Promise<Result<MetadataResponse, SearchServiceError>>; | ||
/** | ||
* Fetch the metadata value for a given identifier and keypath | ||
* | ||
* The response from this request can take any form, object, array, string, etc. | ||
* depending on the query. You can provide return typing in the response by | ||
* specifying the type. Note, there is no automatic type conversion since it can be anything. | ||
* | ||
* For example: | ||
* | ||
* ```ts | ||
* const collection = await searchService.fetchMetadataValue<string>('goody', 'metadata/collection/0'); | ||
* console.debug('collection:', collection); => 'Goody Collection' | ||
* | ||
* const files_count = await searchService.fetchMetadataValue<number>('goody', 'files_count'); | ||
* console.debug('files_count:', files_count); => 12 | ||
* ``` | ||
* | ||
* Keypath examples: | ||
* | ||
* /metadata/:identifier/metadata // returns the entire metadata object | ||
* /metadata/:identifier/server // returns the server for the given identifier | ||
* /metadata/:identifier/files_count | ||
* /metadata/:identifier/files?start=1&count=2 // query for files | ||
* /metadata/:identifier/metadata/collection // all collections | ||
* /metadata/:identifier/metadata/collection/0 // first collection | ||
* /metadata/:identifier/metadata/title | ||
* /metadata/:identifier/files/0/name // first file name | ||
* | ||
* @param identifier | ||
* @param keypath | ||
*/ | ||
fetchMetadataValue<T>(identifier: string, keypath: string): Promise<Result<T, SearchServiceError>>; | ||
} |
@@ -21,2 +21,3 @@ import { SearchResponse } from './responses/search/search-response'; | ||
fetchMetadata(identifier: string): Promise<Result<MetadataResponse, SearchServiceError>>; | ||
fetchMetadataValue<T>(identifier: string, keypath: string): Promise<Result<T, SearchServiceError>>; | ||
} |
@@ -38,4 +38,17 @@ import { SearchResponse } from './responses/search/search-response'; | ||
} | ||
async fetchMetadataValue(identifier, keypath) { | ||
var _a; | ||
const result = await this.searchBackend.fetchMetadata(identifier, keypath); | ||
if (result.error) { | ||
return result; | ||
} | ||
if (((_a = result.success) === null || _a === void 0 ? void 0 : _a.result) === undefined) { | ||
return { | ||
error: new SearchServiceError(SearchServiceErrorType.itemNotFound), | ||
}; | ||
} | ||
return { success: result.success.result }; | ||
} | ||
} | ||
SearchService.default = new SearchService(new DefaultSearchBackend()); | ||
//# sourceMappingURL=search-service.js.map |
@@ -45,2 +45,29 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ | ||
}); | ||
describe('requestMetadataValue', async () => { | ||
class MockSearchBackend { | ||
performSearch(params) { | ||
throw new Error('Method not implemented.'); | ||
} | ||
async fetchMetadata(identifier, keypath) { | ||
return { | ||
success: { | ||
result: this.response, | ||
}, | ||
}; | ||
} | ||
} | ||
it('can request a metadata value', async () => { | ||
const backend = new MockSearchBackend(); | ||
const service = new SearchService(backend); | ||
let expectedResult = 'foo'; | ||
backend.response = expectedResult; | ||
let result = await service.fetchMetadataValue('foo', 'metadata'); | ||
expect(result.success).to.equal(expectedResult); | ||
expectedResult = { foo: 'bar' }; | ||
backend.response = expectedResult; | ||
result = await service.fetchMetadataValue('foo', 'metadata'); | ||
expect(result.success).to.equal(expectedResult); | ||
expect(result.success.foo).to.equal('bar'); | ||
}); | ||
}); | ||
it('returns an error result if the item is not found', async () => { | ||
@@ -47,0 +74,0 @@ var _a; |
{ | ||
"name": "@internetarchive/search-service", | ||
"version": "0.1.2", | ||
"version": "0.1.3-alpha.1", | ||
"description": "A search service for the Internet Archive", | ||
@@ -35,3 +35,3 @@ "license": "AGPL-3.0-only", | ||
"@web/dev-server": "^0.0.12", | ||
"@web/test-runner": "^0.7.41", | ||
"@web/test-runner": "^0.13.23", | ||
"concurrently": "^5.1.0", | ||
@@ -38,0 +38,0 @@ "eslint": "^7.21.0", |
@@ -30,5 +30,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
async fetchMetadata( | ||
identifier: string | ||
identifier: string, | ||
keypath?: string | ||
): Promise<Result<any, SearchServiceError>> { | ||
const url = `https://${this.baseUrl}/metadata/${identifier}`; | ||
const path = keypath ? `/${keypath}` : ''; | ||
const url = `https://${this.baseUrl}/metadata/${identifier}${path}`; | ||
return this.fetchUrl(url); | ||
@@ -45,3 +47,8 @@ } | ||
} catch (err) { | ||
const message = err instanceof Error ? err.message : err; | ||
const message = | ||
err instanceof Error | ||
? err.message | ||
: typeof err === 'string' | ||
? err | ||
: 'Unknown error'; | ||
return this.getErrorResult(SearchServiceErrorType.networkError, message); | ||
@@ -68,3 +75,8 @@ } | ||
} catch (err) { | ||
const message = err instanceof Error ? err.message : err; | ||
const message = | ||
err instanceof Error | ||
? err.message | ||
: typeof err === 'string' | ||
? err | ||
: 'Unknown error'; | ||
return this.getErrorResult(SearchServiceErrorType.decodingError, message); | ||
@@ -71,0 +83,0 @@ } |
@@ -21,3 +21,6 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ | ||
performSearch(params: SearchParams): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata(identifier: string): Promise<Result<any, SearchServiceError>>; | ||
fetchMetadata( | ||
identifier: string, | ||
keypath?: string | ||
): Promise<Result<any, SearchServiceError>>; | ||
} |
@@ -29,2 +29,38 @@ import { MetadataResponse } from './responses/metadata/metadata-response'; | ||
): Promise<Result<MetadataResponse, SearchServiceError>>; | ||
/** | ||
* Fetch the metadata value for a given identifier and keypath | ||
* | ||
* The response from this request can take any form, object, array, string, etc. | ||
* depending on the query. You can provide return typing in the response by | ||
* specifying the type. Note, there is no automatic type conversion since it can be anything. | ||
* | ||
* For example: | ||
* | ||
* ```ts | ||
* const collection = await searchService.fetchMetadataValue<string>('goody', 'metadata/collection/0'); | ||
* console.debug('collection:', collection); => 'Goody Collection' | ||
* | ||
* const files_count = await searchService.fetchMetadataValue<number>('goody', 'files_count'); | ||
* console.debug('files_count:', files_count); => 12 | ||
* ``` | ||
* | ||
* Keypath examples: | ||
* | ||
* /metadata/:identifier/metadata // returns the entire metadata object | ||
* /metadata/:identifier/server // returns the server for the given identifier | ||
* /metadata/:identifier/files_count | ||
* /metadata/:identifier/files?start=1&count=2 // query for files | ||
* /metadata/:identifier/metadata/collection // all collections | ||
* /metadata/:identifier/metadata/collection/0 // first collection | ||
* /metadata/:identifier/metadata/title | ||
* /metadata/:identifier/files/0/name // first file name | ||
* | ||
* @param identifier | ||
* @param keypath | ||
*/ | ||
fetchMetadataValue<T>( | ||
identifier: string, | ||
keypath: string | ||
): Promise<Result<T, SearchServiceError>>; | ||
} |
@@ -60,2 +60,20 @@ import { SearchResponse } from './responses/search/search-response'; | ||
} | ||
async fetchMetadataValue<T>( | ||
identifier: string, | ||
keypath: string | ||
): Promise<Result<T, SearchServiceError>> { | ||
const result = await this.searchBackend.fetchMetadata(identifier, keypath); | ||
if (result.error) { | ||
return result; | ||
} | ||
if (result.success?.result === undefined) { | ||
return { | ||
error: new SearchServiceError(SearchServiceErrorType.itemNotFound), | ||
}; | ||
} | ||
return { success: result.success.result }; | ||
} | ||
} |
@@ -70,2 +70,47 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ | ||
describe('requestMetadataValue', async () => { | ||
class MockSearchBackend implements SearchBackendInterface { | ||
response: any; | ||
performSearch( | ||
params: SearchParams | ||
): Promise<Result<SearchResponse, SearchServiceError>> { | ||
throw new Error('Method not implemented.'); | ||
} | ||
async fetchMetadata( | ||
identifier: string, | ||
keypath?: string | ||
): Promise<Result<any, SearchServiceError>> { | ||
return { | ||
success: { | ||
result: this.response, | ||
}, | ||
}; | ||
} | ||
} | ||
it('can request a metadata value', async () => { | ||
const backend = new MockSearchBackend(); | ||
const service = new SearchService(backend); | ||
let expectedResult: any = 'foo'; | ||
backend.response = expectedResult; | ||
let result = await service.fetchMetadataValue<typeof expectedResult>( | ||
'foo', | ||
'metadata' | ||
); | ||
expect(result.success).to.equal(expectedResult); | ||
expectedResult = { foo: 'bar' }; | ||
backend.response = expectedResult; | ||
result = await service.fetchMetadataValue<typeof expectedResult>( | ||
'foo', | ||
'metadata' | ||
); | ||
expect(result.success).to.equal(expectedResult); | ||
expect(result.success.foo).to.equal('bar'); | ||
}); | ||
}); | ||
it('returns an error result if the item is not found', async () => { | ||
@@ -72,0 +117,0 @@ class MockSearchBackend implements SearchBackendInterface { |
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
289377
149
3813