As of now Tento only supports one schema file.
Get Started with Tento
Build by drizzle team
Tento - is simple yet powerful API for working with Shopify data, including metaobjects, metafields and products. It also provides a CLI tool for two-way synchronization between your local schema definition and Shopify.
- @shopify/shopify-api - package for access for the Shopify Admin API - read here
- dotenv - package for managing environment variables - read here
- tsx - package for running TypeScript files - read here
- Understanding of Shopify Metaobject instance - read here
- Understanding of Shopify Metafield instance - read here
- Get started with OAuth - read here
- Migrations
tento.config.ts
fundamentals - read here
Step 1 - Install dependencies
npm i @drizzle-team/tento
Step 2 - Setup connection variables
Create a .env
file in the root of your project and add your Shopify Access Token variable:
SHOPIFY_ACCESS_TOKEN=
SHOPIFY_SHOP_ID=
Step 3 - Declare schema file
Create a schema.ts
file and declare your metaobjects and metafields schema:
import { metaobject, metafield } from '@drizzle-team/tento';
export const description = metafield({
name: "Description",
key: "description",
namespace: "custom",
ownerType: "PRODUCT",
fieldDefinition: (f) => f.multiLineTextField(),
});
export const designer = metaobject({
name: "Designer",
type: "designer",
fieldDefinitions: (f) => ({
name: f.singleLineTextField({
name: "Title",
required: true,
validations: (v) => [v.min(1), v.max(50)],
}),
description: f.multiLineTextField({
name: "Description",
}),
website: f.url({
name: "Website",
}),
}),
});
Step 4 - Connect Tento client
Create a index.ts
file and initialize the connection:
import 'dotenv/config';
import '@shopify/shopify-api/adapters/web-api';
import * as schema from './db/schema';
import { createClient, tento } from '@drizzle-team/tento';
const client = tento({
client: createClient({
shop: process.env.SHOPIFY_SHOP_ID!,
headers: {
"X-Shopify-Access-Token": process.env.SHOPIFY_ACCESS_TOKEN!,
},
}),
schema,
});
Step 5 - Setup Tento config file
Tento config - a configuration file that is used by Tento CLI and contains all the information about your Shopify connection and schema files.
Create a tento.config.ts
file in the root of your project and add the following content:
import 'dotenv/config';
import { defineConfig } from "@drizzle-team/tento/cli";
export default defineConfig({
schemaPath: './src/schema.ts',
shop: process.env.SHOPIFY_SHOP_ID!,
headers: {
'X-Shopify-Access-Token': process.env.SHOPIFY_ACCESS_TOKEN!,
},
});
Step 6 - Applying changes to the Shopify
You can directly apply changes to your Shopify store using the tento push
command, or using client method applySchema()
:
npx tento push
Read more about migration process in documentation.
Step 7 - Query the Shopify
Let’s update the src/index.ts
file with queries to create, read, update, and delete designers
import 'dotenv/config';
import '@shopify/shopify-api/adapters/web-api';
import * as schema from './db/schema';
import { createClient, tento } from '@drizzle-team/tento';
const client = tento({
client: createClient({
shop: process.env.SHOPIFY_SHOP_ID!,
headers: {
"X-Shopify-Access-Token": process.env.SHOPIFY_ACCESS_TOKEN!,
},
}),
schema,
});
async function main() {
await client.applySchema();
const designer: typeof client.metaobjects.designer.$inferInsert = {
name: "John",
description: "John is designer",
website: "",
};
const createdDesigner = await client.metaobjects.designer.insert(designer);
console.log("New designer created!");
const designers = await client.metaobjects.designer.list({
first: 50
});
console.log('Getting first 50 designers from the Shopify: ', designers)
/*
const designers: {
items: {
_id: string;
_handle: string;
_displayName: string;
_updatedAt: Date;
name: string;
description: string | null;
website: string | null;
}[];
pageInfo: {
startCursor: string;
endCursor: string;
hasNextPage: boolean;
hasPreviousPage: boolean;
};
}
*/
await client.metaobjects.designer.update(createdDesigner._id, {
fields: {
description: "John is designer!",
},
});
console.log("Designer info updated");
await client.metaobjects.designer.delete(createdDesigner._id);
console.log("Designer deleted");
}
Step 8 - Run index.ts file
To run any TypeScript files, you have several options, but let’s stick with one: using tsx
You’ve already installed tsx
, so we can run our queries now
Run index.ts
script
npx tsx src/index.ts