Skip to content

Database

By default, the module uses an SQLite database to store data. However, it can be configured to use PostgreSQL, or Cloudflare D1.

This is the default database type. The DB file is located in a db folder under the current working directory (process.cwd()) by default. To override this, please define a custom path:

index.js
configuration.dbFolder = import.meta.dirname + '/custom_folder';
index.js
configuration.postgreConfig = {
host: 'localhost',
user: 'postgres',
password: 'password',
database: 'test'
};

To migrate from SQLite to PostgreSQL, add the migrateToPostgreFromSQLite option to your configuration object:

index.js
configuration.migrateToPostgreFromSQLite = true;

If the migration fails, check your logs for error details. To roll back to SQLite:

  • Remove the postgreConfig option
  • Set migrateToPostgreFromSQLite option to false

Cloudflare D1 is a serverless SQL database for Workers deployments. Database tables are created automatically on first request (lazy migrations).

index.js
configuration.d1Config = {
database, // D1 database binding from Cloudflare Workers environment
};

Setup: Create database with npx wrangler d1 create my-app-db, add binding to wrangler.toml, and configure as shown above.

The SDK provides the metadataStore to store metadata. Metadata is a key-value pair that can be used to store any data that is not directly related to the main data model. For example, you can store settings, user preferences, etc.

index.js
import crowdinModule from '@crowdin/app-project-module';
const configuration = {
// ...
};
const crowdinApp = crowdinModule.createApp(configuration);
// ...
crowdinApp.saveMetadata({ id: 'key', metadata: 'metadata', crowdinId: 'crowdinId' });
crowdinApp.getMetadata('key');

Used to save some metadata to be used in other parts of the application. It might be associated with an organization, project, etc.

  • id - string - The id of the metadata.
  • metadata - any - The metadata to be saved.
  • crowdinId - string - The organization ID or domain of the Crowdin project. This parameter is required and must be a valid Crowdin ID. If not provided, the function will throw an error. The ID can be obtained from the JWT payload jwtPayload.domain for Enterprise and jwtPayload.context.organization_id for Crowdin.

Used to get metadata.

  • id - string - The id of the metadata.

Used to delete metadata. Usually useful in the onUninstall hook.

  • id - string - The id of the metadata.

Used to get settings that users manage in the integration module.

  • clientId - string - The id of the user.

The module also allows you to define custom tables, manage migrations, and use Drizzle ORM for CRUD operations.

Under the hood, the module uses Drizzle ORM, giving you access to its full capabilities.

As a prerequisite, install these dependencies:

Terminal window
npm install drizzle-orm drizzle-kit

Create a file schema.js:

import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
export const customTable = sqliteTable('custom_tbl', {
id: text('id').primaryKey(),
text: text('custom_text'),
number: integer('custom_number'),
});

Create a config file config.js:

export default defineConfig({
schema: './schema.js',
out: './migrations',
dialect: 'sqlite',
});

Then run:

Terminal window
npx drizzle-kit generate --config ./config.js

This command syncs your schema with migrations and creates any missing migration files.

For Cloudflare D1, declare migrations manually:

const migrations = [
{
name: 'create_custom_table',
run: async (db) => {
const sql = 'CREATE TABLE custom_tbl (id text PRIMARY KEY NOT NULL, custom_text text, custom_number integer)';
await db.$client.prepare(sql).run();
},
},
];
index.js
import * as schema from './schema.js';
configuration.customTables = {
schema,
// for SQLite or PostgreSQL
migrationFolder: './migrations',
// for D1
d1Migrations: migrations,
};

For type safety, you also need a TypeScript file types.ts with the type declaration:

import * as schema from './schema.js';
export type DB = import('drizzle-orm/better-sqlite3').BetterSQLite3Database<typeof schema>;
index.js
import { eq } from 'drizzle-orm';
/** @type {import('./types').DB} */
// @ts-ignore
const db = crowdinApp.storage.db;
const result = await db.query.customTable.findMany({
where: eq(schema.customTable.text, 'some value'),
});
await db.insert(schema.customTable).values({
text: 'text',
number: 123,
});
await db.update(schema.customTable)
.set({ text: 'text' })
.where(eq(schema.customTable.number, 123));
await db.delete(schema.customTable).where(eq(schema.customTable.number, 123));

For more examples please check Drizzle documentation