Get Started with Tento
This guide assumes familiarity with:
@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
Step 1 - Install dependencies
npm i @drizzle-team/tento
yarn add @drizzle-team/tento
pnpm add @drizzle-team/tento
bun add @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=
tips
If you don’t have an active session with accessToken
variable yet and want to create one for testing, you can use our guide Get started with OAuth.
The Get started with OAuth guide is available here .
Step 3 - Declare schema file
Create a schema.ts
file and declare your metaobjects and metafields schema:
info
As of now Tento only supports one schema file.
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" ,
}) ,
}) ,
});
tips
If you don’t have knowledge about Shopify metaobjects and metafields yet, or you want to see full possibilities for those, you can study them on Shopify.
Metaobjects here .
Metafields here .
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
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 ();
}
main ();
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
yarn tsx src/index.ts
pnpm tsx src/index.ts
bun tsx src/index.ts