Security News
ESLint is Now Language-Agnostic: Linting JSON, Markdown, and Beyond
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
@spree/storefront-api-v2-sdk
Advanced tools
Node module to easily integrate your JavaScript or TypeScript application with Spree API V2. You can create an entirely custom Storefront in JS/TS with this package including one page checkout, Single Page Apps, PWAs and so on
Node module to easily integrate your JavaScript or TypeScript application with Spree API V2. You can create an entirely custom Storefront in JS/TS with this package including one page checkout, Single Page Apps, PWAs and so on.
Developed and maintained by:
Š”ontents:
npm install @spree/storefront-api-v2-sdk --save
import { makeClient } from '@spree/storefront-api-v2-sdk'
// When using the SDK in a <script> tag or as part of a Webpack bundle
// targeted for the browser, instead use:
// import { makeClient } from '@spree/storefront-api-v2-sdk/dist/client'
const client = makeClient({
host: 'http://localhost:3000'
})
TypeScript definitions are included in the module and should be automatically used by any editor that supports them.
client
allows calling Spree methods, ex.:
client.products.list({
include: 'default_variant',
page: 1
})
Client
methods return a result object. When a request succeeds, the data received from Spree is retrievable using its success()
method and provided in the JSON:API format. isSuccess()
tells if a request succeeded.
The SDK avoids throwing JavaScript Error
s. Instead, any error is included in a result object.
To determine whether a call was successful, use isSuccess()
or isFail()
methods on the result. Details of a failed call can be retrieved using fail()
. The method returns a SpreeSDKError
instance, which is the primary type for all Error
s returned by the SDK and extends the native JavaScript Error
type.
Available SpreeSDKError
subtypes:
Class Name | Purpose |
---|---|
MisconfigurationError | Signifies the SDK's Client was created with improper options. Make sure the values of host and other options (if any) provided to Client have the correct format. |
NoResponseError | Spree store could not be reached. Ensure it's running and available under the host address provided to the Client instance. |
SpreeError | Spree responded with an error. To debug the issue, check the error's serverResponse field. It contains details about the response from Spree, such as the HTTP status code and headers. |
BasicSpreeError | Extends SpreeError with a error field provided by Spree and containing a summary of the issue. |
ExpandedSpreeError | Extends BasicSpreeError with a errors field. errors contains a detailed explanation of the issue, ex. all the validation errors when trying to add shipping details to a Spree order. The getErrors method can be used to retrieve a concrete value inside errors , ex. expSpreeError.getErrors(['bill_address', 'firstname']) . |
The specific type of error returned by fail()
can be determined using instanceof
, ex. if(response.fail() instanceof BasicSpreeError){...}
.
Spree Storefront API SDK contains each endpoint according to Spree Guides
getToken
Method getToken
creates a Bearer token required to authorize OAuth API calls.
parameters schema:
username: string
password: string
grant_type: string = 'password'
success response schema:
access_token: string
token_type: string = 'Bearer'
expires_in: number
refresh_token: string
created_at: number
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
} catch (err) {
console.error(err)
}
refreshToken
Method refreshToken
refreshes a Bearer token required to authorize OAuth API calls.
parameters schema:
refresh_token: string
success response schema:
access_token: string
token_type: string = 'Bearer'
expires_in: number
refresh_token: string
created_at: number
failed response schema: Error schema
Example:
try {
const token = await client.authentication.refreshToken({
refresh_token: 'aebe2886d7dbba6f769e20043e40cfa3447e23ad9d8e82c632f60ed63a2f0df1'
})
} catch (err) {
console.error(err)
}
accountInfo
Returns current user information.
parameters schema:
token: {
bearerToken: string
}
success response schema:
data: {
id: number
type: string
attributes: {
email: string
store_credits: number
completed_orders: number
}
relationships: {
default_billing_address: {
data: {
id: number
type: string
}
}
default_shipping_address: {
data: {
id: number
type: string
}
}
}
}
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const account = await client.account.accountInfo({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
creditCardsList
Returns a list of Credit Cards for the signed in User.
parameters schema:
token: {
bearerToken: string
}
success response schema:
data: [
{
id: number
type: string
attributes: {
cc_type: string
last_digits: string
month: number
year: number
name: string
default: boolean
}
relationships: {
payment_method: {
data: {
id: string
type: string
}
}
}
}
]
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cardsList = await client.account.creditCardsList({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
defaultCreditCard
Return the User's default Credit Card.
parameters schema:
token: {
bearerToken: string
}
success response schema:
data: {
id: number
type: string
attributes: {
cc_type: string
last_digits: string
month: number
year: number
name: string
default: boolean
}
relationships: {
payment_method: {
data: {
id: string
type: string
}
}
}
}
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const defaultCard = await client.account.defaultCreditCard({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
completedOrdersList
Returns Orders placed by the User. Only completed ones.
parameters schema:
token: {
bearerToken: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const ordersList = await client.account.completedOrdersList({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
completedOrder
Return the User's completed Order.
parameters schema:
token: {
bearerToken: string
}
id: string
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const ordersList = await client.account.completedOrder({
bearerToken: token.access_token
}, 'order_id')
} catch (err) {
console.error(err)
}
status
Returns placed Order.
parameters schema:
number: string
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const order = await client.order.status('order_number')
} catch (err) {
console.error(err)
}
create
Creates new Cart and returns it attributes.
optional parameters schema:
{
bearerToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.create({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
const cart = await client.cart.create()
} catch (err) {
console.error(err)
}
show
Returns contents of the cart.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.show({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.show({
orderToken: cart.data.attributes.token
})
} catch (err) {
console.error(err)
}
addItem
Adds a Product Variant to the Cart.
parameters schema:
{
variant_id: string
quantity: number
}
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.addItem({
bearerToken: token.access_token
}, {
variant_id: '1',
quantity: 1
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.addItem({
orderToken: cart.data.attributes.token
}, {
variant_id: '1',
quantity: 1
})
} catch (err) {
console.error(err)
}
setQuantity
Sets the quantity of a given line item. It has to be a positive integer greater than 0.
parameters schema:
{
line_item_id: string
quantity: number
}
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.setQuantity({
bearerToken: token.access_token
}, {
line_item_id: '9',
quantity: 100
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.setQuantity({
orderToken: cart.data.attributes.token
}, {
line_item_id: '9',
quantity: 100
})
} catch (err) {
console.error(err)
}
removeItem
Removes Line Item from Cart.
parameters schema:
line_item_id: string
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.removeItem({
bearerToken: token.access_token
}, '1')
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.removeItem({
orderToken: cart.data.attributes.token
}, '1')
} catch (err) {
console.error(err)
}
emptyCart
Empties the Cart.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
cart = await client.cart.emptyCart({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.emptyCart({
orderToken: cart.data.attributes.token
}, '1')
} catch (err) {
console.error(err)
}
applyCouponCode
Applies a coupon code to the Cart.
parameters schema:
{
coupon_code: string
}
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
cart = await client.cart.applyCouponCode({
bearerToken: token.access_token
}, {
coupon_code: 'promo_test'
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.applyCouponCode({
orderToken: cart.data.attributes.token
}, {
coupon_code: 'promo_test'
})
} catch (err) {
console.error(err)
}
removeCouponCode
Removes a coupon code from the Cart.
parameters schema:
coupon_code: string
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.removeCouponCode({
bearerToken: token.access_token
}, 'promo_test')
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.removeCouponCode({
orderToken: cart.data.attributes.token
}, 'promo_test')
} catch (err) {
console.error(err)
}
estimateShippingMethods
Returns a list of Estimated Shipping Rates for Cart.
parameters schema:
country_iso: string
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const cart = await client.cart.estimateShippingMethods({
bearerToken: token.access_token
}, 'USA')
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.cart.estimateShippingMethods({
orderToken: cart.data.attributes.token
}, 'USA')
} catch (err) {
console.error(err)
}
orderUpdate
Updates the Checkout You can run multiple Checkout updates with different data types.
parameters schema:
order: {
email: string
bill_address_attributes?: {
firstname: string
lastname: string
address1: string
city: string
phone: string
zipcode: string
state_name: string
country_iso: string
}
ship_address_attributes?: {
firstname: string
lastname: string
address1: string
city: string
phone: string
zipcode: string
state_name: string
country_iso: string
}
shipments_attributes?: [
{
selected_shipping_rate_id: number
id: number
}
]
payments_attributes?: [
{
payment_method_id: number
}
]
}
payment_source?: {
[payment_method_id: number]: {
number: string
month: string
year: string
verification_value: string
name: string
}
}
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.orderUpdate({
bearerToken: token.access_token
}, {
order: {
email: 'john@snow.org',
bill_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
ship_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
shipments_attributes: [{
id: 1,
selected_shipping_rate_id: 1
}],
payments_attributes: [{
payment_method_id: 1
}]
},
payment_source: {
1: {
number: '4111111111111111',
month: '1',
year: '2022',
verification_value: '123',
name: 'John Doe'
}
}
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
cart = await client.checkout.orderUpdate({
orderToken: cart.data.attributes.token
}, {
order: {
email: 'john@snow.org',
bill_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
ship_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
shipments_attributes: [{
id: 1,
selected_shipping_rate_id: 1
}],
payments_attributes: [{
payment_method_id: 1
}]
},
payment_source: {
1: {
number: '4111111111111111',
month: '1',
year: '2022',
verification_value: '123',
name: 'John Doe'
}
}
})
} catch (err) {
console.error(err)
}
orderNext
Goes to the next Checkout step.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.orderNext({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.orderNext({
orderToken: token.access_token
})
} catch (err) {
console.error(err)
}
advance
Advances Checkout to the furthest Checkout step validation allows, until the Complete step.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.advance({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.advance({
orderToken: token.access_token
})
} catch (err) {
console.error(err)
}
complete
Completes the Checkout.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.complete({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.complete({
orderToken: token.access_token
})
} catch (err) {
console.error(err)
}
addStoreCredits
Adds Store Credit payments if a user has any.
parameters schema:
{
amount: number
}
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.addStoreCredits({
bearerToken: token.access_token
}, {
amount: 100
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.addStoreCredits({
orderToken: token.access_token
}, {
amount: 100
})
} catch (err) {
console.error(err)
}
removeStoreCredits
Remove Store Credit payments if any applied.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema: Success schema
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.removeStoreCredits({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.removeStoreCredits({
orderToken: token.access_token
})
} catch (err) {
console.error(err)
}
paymentMethods
Returns a list of available Payment Methods.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
success response schema:
{
data: [
{
id: atring
type: string
attributes: {
type: string
name: string
description: string
}
}
]
}
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.paymentMethods({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.paymentMethods({
orderToken: token.access_token
})
} catch (err) {
console.error(err)
}
shippingMethods
Returns a list of available Shipping Rates for Checkout. Shipping Rates are grouped against Shipments. Each checkout cna have multiple Shipments eg. some products are available in stock and will be send out instantly and some needs to be backordered.
optional parameters schema:
{
bearerToken?: string
orderToken?: string
}
{
params?: {
include?: string
}
}
success response schema:
{
data: [
{
id: atring
type: string
attributes: {
type: string
name: string
description: string
}
}
]
}
failed response schema: Error schema
Example:
try {
const token = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
const order = await client.checkout.shippingMethods(
{ bearerToken: token.access_token },
{ include: 'shipping_rates' }
)
} catch (err) {
console.error(err)
}
// or
try {
let cart = await client.cart.create()
const order = await client.checkout.shippingMethods(
{ orderToken: token.access_token },
{ include: 'shipping_rates' }
)
} catch (err) {
console.error(err)
}
try {
const { access_token: accessToken } = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
await client.cart.create({
bearerToken: accessToken
})
await client.cart.addItem({
bearerToken: accessToken
}, {
variant_id: '1'
})
const shipping = await client.checkout.shippingMethods({
bearerToken: accessToken
})
const payment = await client.checkout.paymentMethods({
bearerToken: accessToken
})
let order = await client.checkout.orderUpdate({
bearerToken: token.access_token
}, {
order: {
email: 'john@snow.org',
bill_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
ship_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
shipments_attributes: [{
id: shipping.data[0].id,
selected_shipping_rate_id: shipping.data[0].relationships.shipping_rates.data[0].id
}],
payments_attributes: [{
payment_method_id: payment.data[0].id
}]
},
payment_source: {
[payment.data[0].id]: {
number: '4111111111111111',
month: '1',
year: '2022',
verification_value: '123',
name: 'John Doe'
}
}
})
order = await client.checkout.complete({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
try {
const { access_token: accessToken } = await client.authentication.getToken({
username: 'spree@example.com',
password: 'spree123'
})
await client.cart.create({
bearerToken: accessToken
})
await client.cart.addItem({
bearerToken: accessToken
}, {
variant_id: '1'
})
// Step one
let order = await client.checkout.orderUpdate({
bearerToken: token.access_token
}, {
order: {
email: 'john@snow.org',
bill_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
},
ship_address_attributes: {
firstname: 'John',
lastname: 'Snow',
address1: '7735 Old Georgetown Road',
city: 'Bethesda',
phone: '3014445002',
zipcode: '20814',
state_name: 'MD',
country_iso: 'US'
}
},
})
await client.checkout.orderNext({
bearerToken: accessToken
})
// Step two
const shipping = await client.checkout.shippingMethods({
bearerToken: accessToken
})
let order = await client.checkout.orderUpdate({
bearerToken: token.access_token
}, {
order: {
shipments_attributes: [{
id: shipping.data[0].id,
selected_shipping_rate_id: shipping.data[0].relationships.shipping_rates.data[0].id
}]
}
})
await client.checkout.orderNext({
bearerToken: accessToken
})
// Step three
const payment = await client.checkout.paymentMethods({
bearerToken: accessToken
})
let order = await client.checkout.orderUpdate({
bearerToken: token.access_token
}, {
order: {
payments_attributes: [{
payment_method_id: payment.data[0].id
}]
},
payment_source: {
[payment.data[0].id]: {
number: '4111111111111111',
month: '1',
year: '2022',
verification_value: '123',
name: 'John Doe'
}
}
})
// Order complete
await client.checkout.orderNext({
bearerToken: accessToken
})
order = await client.checkout.complete({
bearerToken: token.access_token
})
} catch (err) {
console.error(err)
}
Returns a list of Products.
list
optional parameters schema:
{
include?: string
fields?: {
[key: string]: string
}
filter?: {
[key: string]: number
}
sort?: string
page?: number
per_page?: number
}
failed response schema: Error schema
Example:
try {
const products = await client.products.list()
} catch (err) {
console.error(err)
}
list
optional parameters schema:
{
id: string
params?: {
include: string
fields: {
[key: string]: string
}
}
}
failed response schema: Error schema
Example:
try {
const products = await client.products.show('product_id')
} catch (err) {
console.error(err)
}
list
Returns a list of Taxons.
optional parameters schema:
{
include?: string
fields?: {
[key: string]: string
}
filter?: {
[key: string]: number
}
page?: number
per_page?: number
}
failed response schema: Error schema
Example:
try {
const products = await client.taxons.list()
} catch (err) {
console.error(err)
}
show
Returns a single Taxon.
optional parameters schema:
{
id: string
params?: {
include: string
fields: {
[key: string]: string
}
}
}
failed response schema: Error schema
Example:
try {
const products = await client.taxons.show('taxon_id')
} catch (err) {
console.error(err)
}
Spree is maintained by Spark Solutions Sp. z o.o..
We are passionate about open source software. We are available for hire.
FAQs
Node module to easily integrate your JavaScript or TypeScript application with Spree Storefront API V2. You can create an entirely custom Storefront in JS/TS with this package including one page checkout, Single Page Apps, PWAs and so on.
The npm package @spree/storefront-api-v2-sdk receives a total of 1,169 weekly downloads. As such, @spree/storefront-api-v2-sdk popularity was classified as popular.
We found that @spree/storefront-api-v2-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.Ā It has 4 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
ESLint has added JSON and Markdown linting support with new officially-supported plugins, expanding its versatility beyond JavaScript.
Security News
Members Hub is conducting large-scale campaigns to artificially boost Discord server metrics, undermining community trust and platform integrity.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.