Skip to content

Commit 78f97db

Browse files
DanieleFedeliDaniele Fedeli
andauthored
Typed Lyra.insert method according to the schema used (#20)
* Implemented nested schema * Restored old code format * Typed insert function according to the schema inserted * Restored code format * Assed @ts-expect-error in test files Co-authored-by: Daniele Fedeli <[email protected]>
1 parent 441d014 commit 78f97db

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

packages/lyra/src/lyra.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,18 @@ import * as ERRORS from "./errors";
66
import { tokenize } from "./tokenizer";
77
import { formatNanoseconds, getNanosecondsTime } from "./utils";
88
import { Language, SUPPORTED_LANGUAGES } from "./stemmer";
9+
import type { ResolveSchema } from "./types";
910

1011
export type PropertyType = "string" | "number" | "boolean";
1112

1213
export type PropertiesSchema = {
1314
[key: string]: PropertyType | PropertiesSchema;
1415
};
1516

16-
export type LyraProperties = {
17-
schema: PropertiesSchema;
17+
export type LyraProperties<
18+
TSchema extends PropertiesSchema = PropertiesSchema
19+
> = {
20+
schema: TSchema;
1821
defaultLanguage?: Language;
1922
};
2023

@@ -43,18 +46,19 @@ type SearchResult = Promise<{
4346
elapsed: string;
4447
}>;
4548

46-
export class Lyra {
49+
export class Lyra<TSchema extends PropertiesSchema = PropertiesSchema> {
4750
private defaultLanguage: Language = "english";
48-
private schema: PropertiesSchema;
51+
private schema: TSchema;
4952
private docs: LyraDocs = new Map();
5053
private index: LyraIndex = new Map();
54+
5155
private queue: queueAsPromised<QueueDocParams> = fastq.promise(
5256
this,
5357
this._insert,
5458
1
5559
);
5660

57-
constructor(properties: LyraProperties) {
61+
constructor(properties: LyraProperties<TSchema>) {
5862
const defaultLanguage =
5963
(properties?.defaultLanguage?.toLowerCase() as Language) ?? "english";
6064

@@ -67,8 +71,8 @@ export class Lyra {
6771
this.buildIndex(properties.schema);
6872
}
6973

70-
private buildIndex(schema: PropertiesSchema, prefix = "") {
71-
for (const prop in schema) {
74+
private buildIndex(schema: TSchema, prefix = "") {
75+
for (const prop of Object.keys(schema)) {
7276
const propType = typeof prop;
7377
const isNested = typeof schema[prop] === "object";
7478

@@ -77,7 +81,7 @@ export class Lyra {
7781
const propName = `${prefix}${prop}`;
7882

7983
if (isNested) {
80-
this.buildIndex(schema[prop] as PropertiesSchema, `${propName}.`);
84+
this.buildIndex(schema[prop] as TSchema, `${propName}.`);
8185
} else {
8286
this.index.set(propName, new Trie());
8387
}
@@ -207,7 +211,7 @@ export class Lyra {
207211
}
208212

209213
public async insert(
210-
doc: object,
214+
doc: ResolveSchema<TSchema>,
211215
language: Language = this.defaultLanguage
212216
): Promise<{ id: string }> {
213217
const id = nanoid();

packages/lyra/src/types.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
1+
import type { PropertiesSchema } from "./lyra";
12
export type Nullable<T> = T | null;
3+
4+
type ResolveTypes<TType> = TType extends "string"
5+
? string
6+
: TType extends "boolean"
7+
? boolean
8+
: TType extends "number"
9+
? number
10+
: TType extends PropertiesSchema
11+
? { [P in keyof TType]: ResolveTypes<TType[P]> }
12+
: never;
13+
14+
export type ResolveSchema<T extends PropertiesSchema> = {
15+
[P in keyof T]: ResolveTypes<T[P]>;
16+
};

packages/lyra/tests/lyra.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ describe("checkInsertDocSchema", () => {
6161
).toBeDefined();
6262

6363
try {
64+
// @ts-expect-error
6465
await db.insert({ quote: "hello, world!", author: true });
6566
} catch (err) {
6667
expect(err).toMatchSnapshot();
@@ -69,13 +70,15 @@ describe("checkInsertDocSchema", () => {
6970
try {
7071
await db.insert({
7172
quote: "hello, world!",
73+
// @ts-expect-error
7274
authors: "author should be singular",
7375
});
7476
} catch (err) {
7577
expect(err).toMatchSnapshot();
7678
}
7779

7880
try {
81+
// @ts-expect-error
7982
await db.insert({ quote: "hello, world!", foo: { bar: 10 } });
8083
} catch (err) {
8184
expect(err).toMatchSnapshot();

0 commit comments

Comments
 (0)