//native
export type DynSelect_location_id = string
export async function location_id(auth: RT.Shopify) {
const response = await fetch(
`https://${auth.store_name}.myshopify.com/admin/api/2026-10/graphql.json`,
{
method: "POST",
headers: {
"X-Shopify-Access-Token": auth.token,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
query: `query { locations(first: 250) { nodes { id name } } }`,
}),
}
)
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const { data, errors } = await response.json()
if (errors) {
throw new Error(JSON.stringify(errors))
}
return data.locations.nodes.map((l: { id: string; name: string }) => ({
value: l.id,
label: l.name,
}))
}
/**
* Update Inventory Level
* Set the available (or on-hand) quantity of an inventory item at a location. The inventory item ID is on each variant (variant.inventoryItem.id). Pass change_from_quantity (the quantity you expect is there now) to fail instead of overwriting a concurrent change; leave it empty to overwrite unconditionally. The item must be tracked and stocked at the location.
*/
export async function main(
auth: RT.Shopify,
inventory_item_id: string,
location_id: DynSelect_location_id,
quantity: number,
name: "available" | "on_hand" | undefined,
reason:
| "correction"
| "cycle_count_available"
| "received"
| "restock"
| "damaged"
| "shrinkage"
| "quality_control"
| "promotion"
| "safety_stock"
| "movement_created"
| "movement_updated"
| "movement_received"
| "movement_canceled"
| "reservation_created"
| "reservation_updated"
| "reservation_deleted"
| "other"
| undefined,
change_from_quantity: number | undefined,
reference_document_uri: string | undefined
) {
const inventoryItemId = inventory_item_id.startsWith("gid://")
? inventory_item_id
: `gid://shopify/InventoryItem/${inventory_item_id}`
const locationId = location_id.startsWith("gid://")
? location_id
: `gid://shopify/Location/${location_id}`
const response = await fetch(
`https://${auth.store_name}.myshopify.com/admin/api/2026-10/graphql.json`,
{
method: "POST",
headers: {
"X-Shopify-Access-Token": auth.token,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
query: `mutation ($input: InventorySetQuantitiesInput!, $key: String!) { inventorySetQuantities(input: $input) @idempotent(key: $key) { inventoryAdjustmentGroup { id createdAt reason referenceDocumentUri changes { name delta quantityAfterChange item { id } location { id name } } } userErrors { field message code } } }`,
variables: {
key: crypto.randomUUID(),
input: {
name: name || "available",
reason: reason || "correction",
referenceDocumentUri: reference_document_uri || undefined,
quantities: [
{
inventoryItemId,
locationId,
quantity,
// mandatory since 2026-04: null skips the compare-and-swap check
changeFromQuantity: change_from_quantity ?? null,
},
],
},
},
}),
}
)
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const { data, errors } = await response.json()
if (errors) {
throw new Error(JSON.stringify(errors))
}
if (data.inventorySetQuantities.userErrors.length) {
throw new Error(JSON.stringify(data.inventorySetQuantities.userErrors))
}
return data.inventorySetQuantities
}
Submitted by hugo989 3 hours ago