Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support full-text index decorator in babel plugin #6218

Merged
merged 2 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions packages/babel-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ Note that use of decorators requires using the `@babel/plugin-proposal-decorator

This table shows the available decorators:

| Decorator | Parameters | Notes |
| --------- | ----------------------------- | ---------------------------------------------------------------------------------------------------- |
| `index` | none | Specifies that the decorated property should be indexed by Realm. |
| `mapTo` | `(realmPropertyName: string)` | Specifies that the decorated property should be stored as `realmPropertyName` in the Realm database. |
| Decorator | Parameters | Notes |
|-----------|-------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `index` | none 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:

Expand All @@ -219,8 +219,11 @@ import { mapTo, index } from "@realm/babel-plugin";

export class Task extends Realm.Object {
_id!: Realm.BSON.ObjectId;
// Add an index to the `description` property
// 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")
Expand Down
33 changes: 33 additions & 0 deletions packages/babel-plugin/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,39 @@ describe("Babel plugin", () => {
expect(transformCode).not.toContain("_applyDecoratedDescriptor");
});

it('handles `@index("full-text")` decorators', () => {
const transformCode = transformProperty(`@index("full-text") name: Realm.Types.String;`);
const parsedSchema = extractSchema(transformCode);

expect((parsedSchema?.properties.name as PropertySchema).indexed).toEqual("full-text");
})

it('handles `@index("full-text")` decorators from the Realm import', () => {
const transformCode = transform({
source: `import Realm, { Types, BSON, List, Set, Dictionary, Mixed } from "realm";
export class Person extends Realm.Object { @Realm.index("full-text") name: Realm.Types.String; }`,
});
const parsedSchema = extractSchema(transformCode);

expect((parsedSchema?.properties.name as PropertySchema).indexed).toEqual("full-text");
});

it('ignores `@index("full-text")` decorators not imported from `realm`', () => {
const transformCode = transform({
source: `import Realm, { Types, BSON, List, Set, Dictionary, Mixed } from "realm";
export class Person extends Realm.Object { @index("full-text") name: Realm.Types.String; }`,
});
const parsedSchema = extractSchema(transformCode);

expect((parsedSchema?.properties.name as PropertySchema).indexed).toBeUndefined();
});

it('removes `@index("full-text")` decorators from the source', () => {
const transformCode = transformProperty(`@index("full-text") name: Realm.Types.String;`);
// This is what Babel outputs for transformed decorators
expect(transformCode).not.toContain("_applyDecoratedDescriptor");
});

it("handles `@mapTo` decorators", () => {
const transformCode = transformProperty(`@mapTo("rename") name: Realm.Types.String;`);
const parsedSchema = extractSchema(transformCode);
Expand Down
12 changes: 12 additions & 0 deletions packages/babel-plugin/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,13 @@ function visitRealmClassProperty(path: NodePath<types.ClassProperty>) {
}
const index = Boolean(indexDecorator);

const indexDecoratorCall = findDecoratorCall(decoratorsPath, "index");
const indexCall =
indexDecoratorCall
&& types.isStringLiteral(indexDecoratorCall.callExpression.arguments[0])
? indexDecoratorCall.callExpression.arguments[0].value
: undefined;

const mapToDecorator = findDecoratorCall(decoratorsPath, "mapTo");
const mapTo =
mapToDecorator && types.isStringLiteral(mapToDecorator.callExpression.arguments[0])
Expand All @@ -299,6 +306,7 @@ function visitRealmClassProperty(path: NodePath<types.ClassProperty>) {
// Remove the decorators from the final source as they are only for schema annotation purposes.
// Decorator implementations will throw to prevent usage outside of the plugin.
if (indexDecorator) indexDecorator.remove();
if (indexDecoratorCall) indexDecoratorCall.decoratorNode.remove();
if (mapToDecorator) mapToDecorator.decoratorNode.remove();

if (keyPath.isIdentifier()) {
Expand Down Expand Up @@ -336,6 +344,10 @@ function visitRealmClassProperty(path: NodePath<types.ClassProperty>) {
properties.push(types.objectProperty(types.identifier("indexed"), types.booleanLiteral(true)));
}

if (indexCall) {
properties.push(types.objectProperty(types.identifier("indexed"), types.stringLiteral(indexCall)))
}

if (mapTo) {
properties.push(types.objectProperty(types.identifier("mapTo"), types.stringLiteral(mapTo)));
}
Expand Down
Loading