npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@takinola/handy-shopify

v7.0.34

Published

Handy-Shopify is a framework for developing Shopify apps based on the Handyjs framework

Downloads

29

Readme

Handy-Shopify.js Documentation

Introduction

Features

Dependencies

Getting Started

Globals

Globals are set using handy.system.systemGlobal.set(global_name, global_value)

shopify_custom_app

If true, indicates the app is a custom app. Used to bypass functionality that is only applicable to public apps eg billing selection

handy_shopify_default_webhooks

Array of webhooks always set upon installation in the shop (typically, shop/update and shop/uninstall)

API Documentation

Module: handy-shopfy

addPostAppInstallFunctions

Adds new functions that are executed whenever the app is installed on a shop. The functions must return promises and are executed in the context of the shop “this” object

arguments

  • @param {array} functionArray - array of functions to be executed

example

addPostAppInstallFunctions([function_a, function_b,....])

authenticateJWT

Middleware to authenticate calls from front end using JWT Used to authenticate calls from interfaces embedded inside the Shopify admin

arguments

  • @param {object} req - express request object
  • @param {object} res - express response object
  • @param {function} next - express next object

example

let shopifyAdminRouter = express.router

shopifyAdminRouter.use(authenticateJWT)
shopifyAdminRouter.post('/random_path', (req, res)=>{})

Shop

This is the Shop class. It is based on the handy baseObject

Shop objects have the following properties (in addition to those inherited from the handy baseObject) insert property list

Shop objects have the following methods

getAccessScopes

Get list of all access scopes for currently installed app

arguments None

example

let shop = new Shop(...)
const scopes = await shop.getAccessScopes();
// scopes = ['read_theme', 'write_themes', ...]
validateAccessScopes

Middleware to validate shop has all the current access scopes

arguments

  • @param {object} req - Express request object
  • @param {object} res - Express response object
  • @param {object} next - Express next object

example

app.get('/settings', validateAccessScopes, (req, res)=>{
  const myshopify_domain = req.query.shop;  // it is important that the myshopify domain is included in the req.query.shop value
})
getThemes

Gets all themes available in the shop

arguments

  • @param {object} {current} - if true, returns only the published theme otherwise returns all themes

example

let shop = new Shop(...)
let current = true
shop.getThemes({current})
.then((currentTheme)=> /.../)
createAsset

Creates an (or updates an existing) asset in the shop theme

arguments

  • @param {object} asset - asset to be created. format {key: 'eg snippet/my_file.liquid', value: 'eg content of file'}
  • @param {string} themeId - id of the theme where the asset will be created

example

let shop = new Shop(...)
const asset = {
  key: 'snippet/my_file.liquid',
  value: '{{ this is my file }}'
}
const themeId = '124567'
shop.createAsset(asset, themeId)
.then((createdAsset)=> /.../)
getAsset

Get asset from the shop theme

arguments

  • @param {string} key - key of the asset eg "snippet/my_file.liquid"
  • @param {string} themeId - id of the theme where the asset is located

example

let shop = new Shop(...)
const key = 'snippet/my_file.liquid'
const themeId = '1234567'
shop.getAsset(key, themeId)
.then((asset)=> /../)
createScriptTags

Adds script tags to designated shop. This function needs to be bound to the shop that is creating script tags. If using REST API, createShopifyAPI needs to have been run on the shop before calling this function

arguments

  • @param {array} scriptTags - script tags to be created
  • @param {bool} gql - if true, use the GraphQL API

example

let shop = new Shop(...)
const gql = true;
createScriptTags.bind(shop)([
    {
      script_tag: {
        name: 'my tag',
        display_scope: 'ONLINE_STORE',
        src: 'https://path/to/script.js'
      }
    },
    {
      script_tag: {
        name: 'my other tag',
        display_scope: 'ALL',
        src: 'https://path/to/other/script.js'
      }
    }
  ],
  gql)

  // shop.app_settings.scripttags will contain the array of all active script tags
createWebhooks

Adds webhooks to the designated shop. This function needs to be bound to the shop that it is creating webhooks on. Also, createShopifyAPI needs to have been run on the shop before calling this function

arguments

  • @param {object} webhooks - webhooks to be created
  • @param {bool} gql - if yes, use GraphQL API

example

let shop = new Shop(...) 

// GraphQL API example
const gql = true;
createWebhooks.bind(shop)({
  webhook: {
    topic: 'ORDER_CREATE',
    address: 'https://path/webhook/should/call',
    format: 'JSON'
  }
}, gql)


// REST API example
createWebhooks.bind(shop)({
  webhook: {
    topic: ‘orders/create’,
    address: ‘https://path/webhook/should/call’,
    format: ‘json’
  }
})


// shop.app_settings.webhooks will contain the array of active webhooks
resetWebhooks

This recreates the Shopify webhooks for the shop. This is sometimes necessary if the Shopify webhook creation process fails at installation or if new webhooks are to be added to the shop (by updating the 'shopify_default_webhooks' system variable)

arguments

none

example

let shop = new Shop(...)
shop.resetWebhooks()
getOrders

This fetches orders from Shopify

arguments

  • @param {int} orderId - if provided, will retrieve the particular order with that id (not valid for GraphQL API)
  • @param {string} fulfilment_status - if provided will retrieve only orders with that fulfillment status. defaults to 'unfulfilled'
  • @param {boolean} stream - if true, the data will be provided as a stream in chuncks
  • @param {boolean} gql - if true, use GraphQL API
  • @params {array} fields - fields to be returned if using GraphQL API. child customer and line item fields should be prefixed with "customer__" and "line_items__" respectively
  • NOTE: field line items will return data in format
  • lineItems { edges { node { ...requested fields } } }

example

let shop = new Shop(...)
shop.getOrders(null, 'partial')

or
const stream = true;
const orderGetter = shop.getOrders(null, null, stream)
const delimiter = '!@$%^&*()';
handy.system.sendData(orderGetter, delimiter, res)
.then(()=> / continue processing /)
.catch((err)=> / error processing /)

or

const gql = true
const fields = ['id', 'name', 'shippingAddress', 'customer__displayName', 'line_items__id']
const orderId = "gid://shopify/order/123456"
shop.getOrders(orderId, null, null, gql, fields)
.then((orders)=> /.../)
updateOrder

Update existing order NOTE: Only editing with the REST API is enabled

arguments

  • @param {string} id - order id
  • @param {object} order - order object with required parameters
  • @param {boolean} gql - if true, use GraphQL

example

let shop = new Shop(...)
const id = '1234567'
const order = {
  id: '1234567',
  note_attributes: {
    name: 'new attribute',
    value: 'i changed'
  }
}

shop.updateOrder({id, order})
.then((updatedOrder)=> / continue processing /)
.catch((err)=> / error processing /)
createProduct

Create a product in the shop

arguments

  • @param {object} productDefinition - object with the product properties
  • @param {array} fields - fields to be returned if using GraphQL API
  • @param {bool} gql - if true, use GraphQL API

example

let shop = new Shop(...)

const productDefinition = {
  title: 'my product',
  bodyHtml: '<p>Please buy this amazing product</p>',
  vendor: 'Seller Co'
}

const fields = ['id', 'handle', 'tags']
const gql = true

shop.createProduct(productDefinition, fields, gql)
.then(product => /.../)
getProducts

Retrieve the list of products in the shop

arguments

  • @params {array} fields - fields to be returned for each product object
  • NOTE: prefixing fields with "variant__" will get the variant fields. Requesting variant fields will slow down the query considerably
  • @params {array} ids - if provided, only the products with these specific ids will be returned
  • @params {string} handle - if provided, only the product with this handle will be returned
  • @params {string} product_type - if provided, only products with this product type will be returned
  • @params {bool} stream - if true, the data will be provided as a stream in chuncks
  • @params {bool} gql - if true, use GraphQL API
  • [GraphQL only] @params {object} filter - key value parameters to filter results

example

let shop = new Shop(...)

shop.getProducts({fields: ['id', 'handle'], ids: [1234, 5678], handle: 'cool-product', product_type: 'blockbuster', stream: false})
.then((products)=>{ / process products})
.catch((err)=> { / process errors})

or

const productGetter = shop.getProducts({stream: true})
const delimiter = '!@$%^&*()';
handy.system.sendData(productGetter, delimiter, res)
.then(()=> / continue processing)
.catch((err)=> / error processing)

or

const filter = {product_type: 'blockbuster'}
const fields = ['id', 'title', 'description', 'productType', 'variant__id']
const gql = true            // use GraphQL API
shop.getProducts({fields, filter, gql})
.then((products)=> {/ process products})
.catch((err)=> process errors)
getProductVariant

Retrieve a specific product variant

arguments

  • @param {string} id - id of variant to be retrieved
  • @param {array} fields - list of fields to be returned if using GraphQL
  • NOTE: field inventoryItem will return data in format
  • {inventoryItem
  • {
  • id 
  • inventory (first: 100){
  •   edges { node
  •           id
  •           available
  •           location {id name isActive shipsInventory}
  •         }
  • }
  • }
  • }
  • @param {bool} gql - if true, use GraphQL API

example

let shop = new Shop(...)

// REST API
const id = '1234'
shop.getProductVariant(id)
.then(variant => / process variant)

// GraphQL API
const id = "gid://shopify/productVariant/123456"
const fields = ['id', 'price', 'title']
const gql = true
shop.getProductVariant(id, fields, gql)
.then(variant => / process variant)
getAllProductVariants

Retrieve the list of product variants in the shop

arguments

  • @param {array} fields - fields to be returned for each variant object. child product fields should be prefixed with "product__" eg "product__id"
  • @param {object} filter - key value parameters to filter results
  • @param {bool} gql - if true, use GraphQL API

example

let shop = new Shop(...)

const fields = ['id', 'price', 'title']
const filter = {product_type: 'blockbuster'}
const gql = true;
shop.getAllProductVariants({fields, filter, gql})
.then((variants)=> / process variants)
.catch((err)=> / process errors)
createProductVariant

Create a product variant

arguments

  • @params {object} variantDefinition - variant properties
  • @params {array} fields - variant fields to be returned
  • @params {bool} gql - if true, use GraphQL API

example

const fields = ['id', 'price', 'title']
const variantDefinition = {
  price: 10000,
  sku: 'my_variant',
  taxable: true,
  options: 'variant_title'
}

const gql = true;

shop.createProductVariant(variantDefinition, fields, gql)
.then(variant => / process variant)
updateProductVariant

Update an existing product variant

arguments

  • @params {object} variantDefinition - new variant properties. must include id of variant to be updated
  • @params {array} fields - variant fields to be returned
  • @params {bool} gql - if true, use GraphQL API

examples

const fields = ['id', 'price', 'title']
const variantDefinition = {
  price: 20000,
  sku: 'my_variant_updated',
  taxable: true,
  id: "gid://shopify/Variant/123456"
}

const gql = true;

shop.updateProductVariant(variantDefinition, fields, gql)
.then(variant => / process variant)
adjustVariantInventory

Add or remove inventory for specified variant

arguments

  • @params {string} variant_id - GraphQL id of variant
  • @params {int} available_adjustment - quantity to add (or remove, if negative) from inventory
  • NOTE: This method modifies the first active location

examples

const variant_id = 'gid://shopify/ProductVariant/123456'
const available_adjustment = 10

const shop = new Shop(...)
shop.adjustVariantInventory(variant_id, available_adjustment)
.then((inventoryLevelId)=> /.../)
getCustomers

Get the customer details for a shop

arguments

  • @params {array} fields - customer fields to be returned
  • NOTE including the field "metafields" will return all metafields attached to the customer. Requesting metafields will slow the query down considerably
  • @params {array} ids - ids of customers to be returned (when provided for GraphQL, only the customer with the first Id is returned)
  • @params {bool} gql - if true, use GraphQL API
  • @params {bool} stream - if true, the data will be provided as a stream in chuncks (only available with the GraphQL API)

examples

const fields = ['id', 'displayName', 'email']
const gql = true;

const shop = new Shop(...)
shop.getCustomers({fields, gql})
.then((customers)=> / process customers)
updateCustomer

Update a customer record in Shopify

arguments

  • @params {object} customer - customer details to be updated
  • @params {bool} gql - if true, use GraphQL API

examples

const shop = new Shop(...)
const customer = {
  id: 'gid://shopify/Customer/123456789',
  note: 'This is a VIP customer',
  metafields: {
    namespace: 'my app',
    key: 'vip',
    value: 'true',
    valueType: 'STRING',
    id: 'gid://shopify/Metafield/987654321'
  }
}

const gql = true

shop.updateCustomer(customer, gql)
.then((customerRecord)=> / customerRecord === {id} )

How handy-shopifyjs works

License

Credits