Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@realm/babel-plugin

Package Overview
Dependencies
Maintainers
6
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@realm/babel-plugin

Babel plugin making it easier to declare your Realm schema

  • 0.2.0
  • latest
  • npm
  • Socket score

Version published
Weekly downloads
414
decreased by-37.65%
Maintainers
6
Weekly downloads
 
Created
Source

Realm Babel Plugin

Introduction

The Realm Babel plugin enables defining your Realm models using standard Typescript syntax - no need to define a separate schema.

Before: without the Realm Babel pluginAfter: with the Realm Babel plugin
class Task extends Realm.Object<Task, "description"> {
  _id!: Realm.BSON.ObjectId;
  description!: string;
  isComplete!: boolean;

  static schema = {
    name: "Task",
    primaryKey: "_id",
    properties: {
      _id: "objectId",
      description: "string",
      isComplete: {
        type: "bool",
        default: false,
        indexed: true,
      },
    },
  };

  constructor(realm, description: string) {
    super(realm, {
      _id: new Realm.BSON.ObjectId(),
      description,
    });
  }
}
class Task extends Realm.Object<Task, "description"> {
  _id = new Realm.BSON.ObjectId();
  description!: string;
  @index
  isComplete = false;

  static primaryKey = "_id";

  constructor(realm, description: string) {
    super(realm, { description });
  }
}

Features

  • Schema properties can be defined as class properties by using standard TypeScript types or specific Realm.Types types, supporting every Realm type
  • Support for default values using property initialiser syntax
  • Support for specifying additional schema properties (e.g. primary key) using class statics
  • Support for indexing and remapping fields using decorators

Installation

  1. Install the @realm/babel-plugin npm package:

    npm install --save-dev @realm/babel-plugin

  2. If you don't already have it installed, install the @babel/plugin-proposal-decorators package (only required if you need to use the @index or @mapTo decorators):

    npm install --save-dev @babel/plugin-proposal-decorators

    and enable decorators in your tsconfig.json by adding: "experimentalDecorators": true to the compilerOptions.

  3. Update your project's babel.config.js to load these two plugins:

    // Existing babel.config.js content is commented out
    // module.exports = {
      // presets: ['module:metro-react-native-babel-preset'],
    
      // --------------------------
      // Add the following plugins:
      plugins: [
        '@realm/babel-plugin',
        ['@babel/plugin-proposal-decorators', { legacy: true }],
      ],
      // --------------------------
    // };
    
    
  4. If using React Native, you may need to clear your packager cache for it to pick up the new plugins:

    npm start -- --reset-cache

Usage

Defining model properties

To define your Realm models when using this plugin, simply create classes which extend Realm.Object, and define the model's properties using either supported TypeScript types or Realm.Types types (see supported types). It is recommended that you use the non-null assertion operator (!) after the property name, to tell TypeScript that the property will definitely have a value.

You can use property initialiser syntax to specify a default value for a property, which can either be a static value or a function call for dynamic values.

The recommended pattern for constructing new instances with specified values for properties is to define a constructor which takes the properties as additional arguments. The second type parameter of Realm.Object can be used to specify any fields which are required to be specified in the second fields when an instance is constructed with new - all properties are optional by default.

import Realm from "realm";

// Specify that the name and description fields are required when creating an instance with `new`
export class Task extends Realm.Object<Task, "name" | "description"> {
  // Property initialiser syntax with a dynamic value - each instance will have a unique ID
  _id = new Realm.BSON.ObjectId();
  name!: string;
  description!: string;
  // Property initializer syntax with a static value
  isComplete = false;
  // Specifying the type of number to be stored in the Realm using Realm.Types
  count!: Realm.Types.Int = 0;
}

You can also import Object and Types directly from realm:

import { Object, Types, BSON } from "realm";

export class Task extends Object<Task, "name" | "description"> {
  _id = BSON.ObjectId();
  name: string;
  description!: string;
  isComplete = false;
  count!: Types.Int;
}
Supported types

This plugin supports standard TypeScript types wherever possible, to make defining your model as natural as possible. Some Realm types do not have a direct TypeScript equivalent (e.g. double, int and float are all represented by number in TypeScript), so in these cases you should use the types provided by Realm.Types.

As a rule, we recommend using TypeScript types where possible, and using Realm.Types where you cannot, but you can also exclusively use types from Realm.Types if preferred.

Types which are provided by Realm (e.g. Realm.List) are exported from both the top-level Realm namespace, and from Realm.Types - you can use either variant in your models.

The supported types are shown in the table below. See the Realm documentation and SDK documentation for more details on each type.

Realm.Types typeRealm schema typeTypeScript typeRealm typeNotes
Types.Boolboolboolean
Types.Stringstringstring
Types.Intint
Types.Floatfloat
Types.DoubledoublenumberDouble is the default number type
Types.Decimal128decimal128Realm.BSON.Decimal128
Types.ObjectIdobjectIdRealm.BSON.ObjectId
Types.UUIDuuidRealm.BSON.UUID
Types.DatedateDate
Types.DatadataArrayBuffer
Types.List<T>type[]Realm.List<T>T is the type of objects in the list
Types.Set<T>type<>Realm.Set<T>T is the type of objects in the set
Types.Dictionary<T>type{}Realm.Dictionary<T>T is the type of objects in the dictionary
Types.MixedmixedRealm.Mixed
Types.LinkingObjects<T, N>linkingObjectsT is the type of objects, N is the property name of the relationship (as a string)

Specifying schema properties as statics

Additional schema properties can be specified by adding static properties to your class, as shown in the table below. See the Realm documentation for more details.

Static propertyTypeNotes
namestringSpecifies the name of the Realm schema. Defaults to your class name.
primaryKeystringSpecifies the name of a property to be used as the primary key.
embeddedbooleanSpecifies this is an embedded schema.
asymmetricbooleanSpecifies this schema should sync unidirectionally if using flexible sync.

For example:

import Realm from "realm";

export class Task extends Realm.Object<Task, "description"> {
  _id = new Realm.BSON.ObjectId();
  description!: string;
  isComplete = false;

  static primaryKey = "_id";
}

Using decorators to index and remap properties

The @realm/babel-plugin package exports decorators to allow you to specify certain properties should be indexed (using the @index decorators) or should remap to a Realm schema property with a different name (using the @mapTo decorator). To learn more about this functionality, see the documentation.

Note that use of decorators requires using the @babel/plugin-proposal-decorators plugin and for experimentalDecorators to be enabled in your tsconfig.json. There is currently no way to specifying properties to be indexed or remapped without using decorators.

This table shows the available decorators:

DecoratorParametersNotes
indexnone or ("full-text")Specifies that the decorated property should be indexed by Realm. Providing the string "full-text" specifies that the property should be indexed for full-text search by Realm.
mapTo(realmPropertyName: string)Specifies that the decorated property should be stored as realmPropertyName in the Realm database.

The example below shows both decorators in use:

import Realm from "realm";
import { mapTo, index } from "@realm/babel-plugin";

export class Task extends Realm.Object {
  _id!: Realm.BSON.ObjectId;
  // Add an index to the `assignee` property
  @index
  assignee!: string;
  // Specify that the `description` property should be indexed for full-text search
  @index("full-text")
  description!: string;
  // Specify that the `isComplete` property should be stored as `complete` in the Realm database
  @mapTo("complete")
  isComplete = false;
}

Restrictions

All class properties will be added to the Realm schema

There is currently no way to specify a property on your class which should not be persisted to the Realm.

Classes extending Realm.Object cannot be constructed with new outside of a write transaction

This plugin does not change the behaviour of Realm.Object, which cannot be constructed using new outside of a write transaction - there is no concept of a Realm.Object which is not stored in a Realm. Constructing a Realm object with new inside a write transaction will create a new object in the Realm - see class-based models in the CHANGELOG.

Debugging your model

To generate the output for your model (let's say it's located in ./models/task.ts) you can run the babel transpiler manually on the file:

npm install --save-dev @babel/cli @babel/preset-typescript
npx babel --presets @babel/preset-typescript --plugins @realm/babel-plugin ./models/task.ts

Keywords

FAQs

Package last updated on 20 Nov 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc