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
yarn
pnpm
bun
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=
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.

src/db/schema.ts
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:

src/index.ts
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:

tento.config.ts
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():

CLI
Client
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

src/index.ts
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

npm
yarn
pnpm
bun
npx tsx src/index.ts