Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
@spinque/query-api
Advanced tools
[![npm version](https://img.shields.io/npm/v/@spinque/query-api.svg?style=flat-square)](https://www.npmjs.org/package/@spinque/query-api) [![install size](https://packagephobia.now.sh/badge?p=@spinque/query-api)](https://packagephobia.now.sh/result?p=@spi
Library to use the Spinque Query API in your JavaScript/TypeScript project.
The Spinque Query API is an HTTP API to retrieve search results for queries. Also check out the documentation of the Spinque Query API.
Using npm:
$ npm install @spinque/query-api
Documentation for this library can be found here.
For documentation on the Spinque Query API itself, please see this.
Defining a single query:
import { Query } from '@spinque/query-api';
const query: Query = {
endpoint: 'movie_search',
parameters: { terms: 'call me' }
};
Fetching results for a single query using an instance of the Api class and its fetch
method:
import { Api, Query } from '@spinque/query-api';
// Configure the API with workspace, configuration and API name
const api = new Api({
workspace: 'my-workspace',
config: 'default',
api: 'movies'
});
// Construct the query to fetch results for
const query: Query = {
endpoint: 'movie_search',
parameters: { terms: 'call me' }
};
try {
// Fetch the 10 first results of the query
const response = await api.fetch(query, { count: 10 });
} catch (error: any) {
console.error(error);
}
Getting the URL for a request to fetch it using your own HTTP-library of preference:
import { urlFromQueries } from '@spinque/query-api/utils';
const apiConfig = {
workspace: 'my-workspace',
config: 'default',
api: 'movies'
};
const query: Query = {
endpoint: 'movie_search',
parameters: { terms: 'call me' }
};
const url = urlFromQueries(apiConfig, query, { count: 10, offset: 0 });
// Make the request here using `url`
Some Spinque APIs require authentication using OAuth 2.0. The Client Credentials flow (for server applications) and PKCE flow (for browser applications) are provided by @spinque/query-api
:
import { Api } from '@spinque/query-api';
const api = new Api({
workspace: 'my-workspace',
config: 'default',
api: 'movies',
authentication: {
type: 'client-credentials',
clientId: 'abcdefghijklmnopqrstuvwxyz',
clientSecret: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
}
});
const query: Query = {
endpoint: 'movie_search',
parameters: { terms: 'call me' }
};
const response = await api.fetch(queries);
Note: the Client ID and Client Secret can be generated by creating a new System-to-System account in the Settings > Team Members section of Spinque Desk.
import { Api } from '@spinque/query-api';
const api = new Api({
workspace: 'my-workspace',
config: 'default',
api: 'movies',
authentication: {
type: 'pkce',
clientId: 'abcdefghijklmnopqrstuvwxyz',
callback: 'https://my-domain.com/callback'
}
});
const query = {
endpoint: 'movie',
parameters: { id: 'https://imdb.com/data/movie/tt0209144' }
};
const response = await api.fetch(queries, { count: 10, offset: 0 });
Note: the Client ID and Callback URL cannot yet be configured from Spinque Desk. Ask your system administrator to help you out.
Many utility functions are available for import under @spinque/query-api/utils
.
urlFromQueries
, takes an ApiConfig object and an array of Query objects and returns a Spinque Query API request URL.pathFromQuery
, takes a single Query and returns the path of its Spinque Query API URL.pathFromQueries
, takes an array of Query objects and returns the path of their Spinque Query API URL.join
, joints together URL parts into a valid URL.stringifyQueries
, takes an array of Query objects and returns a string representation that can be used to e.g. store in the address baer.parseQueries
, takes a string from stringifyQueries
and tries to parse it into an array of Query objects.stringToTupleList
, given a string, try to parse it as a tuple list (array of arrays of numbers or strings, and array of scores).tupleListToString
, given a tuple list, return a string representation.ensureTupleList
, takes a value (string, number, array of strings or numbers, or array of arrays of strings or numbers) and normalizes it into a tuple list.See the documentation for a complete list.
Faceted search is a common use-case for application built on Spinque. This library provides a FacetedSearch to ease the interaction between queries in a faceted search setup.
The following example shows how a search endpoint 'movie_search' can be used in combination with facet endpoints 'genre' and 'director'.
import { Api, FacetedSearch } from '@spinque/query-api';
const query: Query = {
endpoint: 'movie_search',
parameters: { query: 'call me' }
};
const fs = new FacetedSearch(query);
fs.addFacet('genre', 'multiple');
fs.addFacet('director', 'single');
// Get results and facet options
let results = await api.fetch(fs.getResultsQuery());
let genreOptions = await api.fetch(fs.getFacetQuery('genre'));
let directorOptions = await api.fetch(fs.getFacetQuery('director'));
// Set the search query parameter (e.g. after the user has typed something)
fs.setParameter('query', 'dia');
// Get updated results and options
results = await api.fetch(fs.getResultsQuery());
genreOptions = await api.fetch(fs.getFacetQuery('genre'));
directorOptions = await api.fetch(fs.getFacetQuery('director'));
// Select some facet options
fs.setFacetSelection('genre', ['https://imdb.com/data/Drama', 'https://imdb.com/data/Biography']);
fs.setFacetSelection('director', 'https://imdb.com/data/PabloLarrain');
// Get results again, now with facets applied
results = await api.fetch(fs.getResultsQuery());
Optionally, you can provide a Query for when the search parameters are empty.
...
const listQuery: Query = { endpoint: 'movies' };
const fs = new FacetedSearch(query, listQuery);
Note that the exact same behavior can also be achieved without the FacetedSearch class (though it's more involved). The following two sections produce equal results:
With FacetedSearch:
const query: Query = {
endpoint: 'movie_search',
parameters: { query: 'call me' }
};
const fs = new FacetedSearch(query);
fs.addFacet('genre', 'multiple');
fs.addFacet('director', 'single');
let results = await api.fetch(fs.getResultsQuery());
let genreOptions = await api.fetch(fs.getFacetQuery('genre'));
let directorOptions = await api.fetch(fs.getFacetQuery('director'));
fs.setParameter('query', 'dia');
results = await api.fetch(fs.getResultsQuery());
genreOptions = await api.fetch(fs.getFacetQuery('genre'));
directorOptions = await api.fetch(fs.getFacetQuery('director'));
fs.setFacetSelection('genre', ['https://imdb.com/data/Drama', 'https://imdb.com/data/Biography']);
results = await api.fetch(fs.getResultsQuery());
Without FacetedSearch:
const query: Query = {
endpoint: 'movie_search',
parameters: { query: 'call me' }
};
const genreOptionsQuery: Query = { endpoint: 'genre' };
const genreFilterQuery: Query = {
endpoint: 'genre:FILTER',
parameters: { value: undefined }
};
const directorOptionsQuery: Query = { endpoint: 'director' };
const directorFilterQuery: Query = {
endpoint: 'director:FILTER',
parameters: { value: undefined }
};
let resultsQuery = [query];
if (genreFilterQuery.parameters.value) {
resultsQuery.push(genreFilterQuery);
}
if (directorFilterQuery.parameters.value) {
resultsQuery.push(directorFilterQuery);
}
let results = await api.fetch(resultsQuery);
let genreOptions = await api.fetch([...resultsQuery, genreOptionsQuery]);
let directorOptions = await api.fetch([...resultsQuery, directorOptionsQuery]);
query.parameters.query = 'dia';
let resultsQuery = [query];
if (genreFilterQuery.parameters.value) {
resultsQuery.push(genreFilterQuery);
}
if (directorFilterQuery.parameters.value) {
resultsQuery.push(directorFilterQuery);
}
results = await api.fetch(resultsQuery);
let genreOptions = await api.fetch([...resultsQuery, genreOptionsQuery]);
let directorOptions = await api.fetch([...resultsQuery, directorOptionsQuery]);
genreFilterQuery.parameters.value = tupleListToString(['https://imdb.com/data/Drama', 'https://imdb.com/data/Biography']);
let resultsQuery = [query];
if (genreFilterQuery.parameters.value) {
resultsQuery.push(genreFilterQuery);
}
if (directorFilterQuery.parameters.value) {
resultsQuery.push(directorFilterQuery);
}
results = await api.fetch(resultsQuery);
This library can also be used without using TypeScript:
const sqa = require("@spinque/query-api");
const api = new sqa.Api({
workspace: 'my-workspace',
api: 'movies'
});
const query = {
endpoint: 'search',
parameters: { term: 'utrecht' }
};
try {
const results = await api.fetch(query);
console.log(results);
} catch (error) {
console.log(error);
}
FAQs
[![npm version](https://img.shields.io/npm/v/@spinque/query-api.svg?style=flat-square)](https://www.npmjs.org/package/@spinque/query-api) [![install size](https://packagephobia.now.sh/badge?p=@spinque/query-api)](https://packagephobia.now.sh/result?p=@spi
The npm package @spinque/query-api receives a total of 26 weekly downloads. As such, @spinque/query-api popularity was classified as not popular.
We found that @spinque/query-api demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.