Skip to main content

Using the GAS Editor

GASsma also works from the GAS script editor alone, without the CLI. Once you add the library you can start writing immediately, which suits small scripts or trying things out without setting up a local environment.

This page covers how to write code when using only the GAS editor. For the CLI workflow, see Basics.

note

Both styles use the same library and the same features. The only difference is where you write the configuration: with the CLI you write it in schema.prisma, and with the GAS editor alone you pass it to the constructor.

Adding the Library

Add script ID 1ZVuWMUYs4hVKDCcP3nVw74AY48VqLm50wRceKIQLFKL0wf4Hyou-FIBH as a library. See Installation for the steps.

Once added, you can create a client from the global Gassma namespace.

Creating an Instance

If your GAS project is bound to a spreadsheet (container-bound), you can create an instance with no arguments.

const gassma = new Gassma.GassmaClient();

If you created the GAS project somewhere other than a spreadsheet, or want to work with a different spreadsheet, pass the target spreadsheet ID.

const gassma = new Gassma.GassmaClient("XXXXXXXXXXXXXXXXXXX");

Initialization with an Options Object

When you need configuration such as relation definitions or global omit, pass an options object.

const gassma = new Gassma.GassmaClient({
id: "XXXXXXXXXXXXXXXXXXX", // optional
relations: {
Users: {
posts: { type: "oneToMany", to: "Posts", field: "id", reference: "authorId" },
},
},
omit: {
Users: { password: true },
},
});

lock (Required to Use $transaction)

lock is the lock used by $transaction and by autoincrement when it assigns numbers. When you use the CLI, the generated client fills in the default (LockService.getScriptLock()), but when you write code in the GAS editor you have to pass it yourself.

const gassma = new Gassma.GassmaClient({
lock: LockService.getScriptLock(),
});

Calling $transaction without passing lock throws GassmaTransactionLockRequiredError (autoincrement, on the other hand, keeps going without taking a lock when there is no lock). See Lock for the available granularities.

Constructor Options

OptionDescriptionReference
idSpreadsheet ID (defaults to the active spreadsheet)-
relationsRelation definitionsRelation Definitions
omitGlobal omit settingsGlobal omit
defaultsField default valuesdefaults
updatedAtAuto-updated timestampsupdatedAt
ignoreField-level exclusionignore
ignoreSheetsSheet-level exclusionignore
mapField name mappingmap
mapSheetsSheet name mappingmap
autoincrementAuto-incrementautoincrement
lockLock used by $transaction and autoincrementLock
strictUndefinedChecksTurns explicit undefined in query inputs into runtime errorsstrictUndefinedChecks / Gassma.skip

Schema Equivalents

When using the CLI, most of the options above are written as attributes in schema.prisma.

Constructor optionHow to write it in the schema
relations@relation(fields: [...], references: [...])
defaults@default(...)
autoincrement@default(autoincrement())
updatedAt@updatedAt
ignore@ignore
ignoreSheets@@ignore
map@map("...")
mapSheets@@map("...")
strictUndefinedCheckspreviewFeatures = ["strictUndefinedChecks"]
omitNo schema equivalent (specify it in the constructor even when using the CLI)
lockNo schema equivalent (when using the CLI, the generated client fills in the default)
idThe url of the datasource block, or datasource.url in gassma.config.ts

For details on each setting, see Schema.

About Types

The GAS editor has no generated type definitions, so there is no completion or type checking for sheet names and column names. Mistakes in sheet or column names surface at runtime.

If you want type-safe development, consider using the CLI (Quickstart).

Referring to Error Classes

The error classes GASsma throws are available from the Gassma namespace.

try {
gassma.Users.findFirstOrThrow({ where: { id: 999 } });
} catch (e) {
if (e instanceof Gassma.NotFoundError) {
console.log("Not found");
}
}

For the full list, see Error List.

note

Built-in types such as Date cannot be checked with instanceof across the library boundary. See Basics for details.