@prisma-next/extension-paradedb 0.5.0-dev.81 → 0.5.0-dev.82
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -109
- package/dist/control.d.mts +7 -0
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +1 -1
- package/dist/{descriptor-meta-B6-NIHhB.mjs → descriptor-meta-BF_fQseQ.mjs} +4 -2
- package/dist/descriptor-meta-BF_fQseQ.mjs.map +1 -0
- package/dist/index-types-BWFfNqUb.mjs +11 -0
- package/dist/index-types-BWFfNqUb.mjs.map +1 -0
- package/dist/index-types.d.mts +9 -97
- package/dist/index-types.d.mts.map +1 -1
- package/dist/index-types.mjs +2 -91
- package/dist/pack.d.mts +7 -0
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/package.json +7 -5
- package/src/core/constants.ts +0 -18
- package/src/core/descriptor-meta.ts +2 -0
- package/src/exports/index-types.ts +2 -12
- package/src/types/index-types.ts +12 -179
- package/dist/descriptor-meta-B6-NIHhB.mjs.map +0 -1
- package/dist/index-types.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -4,21 +4,21 @@ ParadeDB full-text search extension pack for Prisma Next.
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This extension pack
|
|
7
|
+
This extension pack registers a `'bm25'` index type with the SQL family's index-type registry, so contracts can author BM25 full-text search indexes via the standard `constraints.index(...)` surface and the Postgres adapter emits `CREATE INDEX ... USING bm25 WITH (...)` DDL.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The v1 surface covers the `key_field` storage parameter only. Per-field tokenizer and column configuration is deferred to expression-index support.
|
|
10
10
|
|
|
11
11
|
## Responsibilities
|
|
12
12
|
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **Pack Ref Export**: Ships a pure `/pack` entrypoint for TypeScript contract authoring
|
|
13
|
+
- **bm25 index registration**: declares a `'bm25'` entry via `defineIndexTypes()` carrying an arktype validator for the bm25 options shape
|
|
14
|
+
- **Extension descriptor**: declares the `paradedb/bm25` capability for contract-level feature detection
|
|
15
|
+
- **Pack ref export**: ships a pure `/pack` entrypoint for TypeScript contract authoring
|
|
17
16
|
|
|
18
17
|
## Dependencies
|
|
19
18
|
|
|
20
|
-
- **`@prisma-next/contract`**:
|
|
21
|
-
- **`@prisma-next/contract-authoring`**:
|
|
19
|
+
- **`@prisma-next/sql-contract`**: index-type registry primitive
|
|
20
|
+
- **`@prisma-next/contract`** / **`@prisma-next/contract-authoring`**: core contract types
|
|
21
|
+
- **`arktype`**: option-shape validation
|
|
22
22
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
@@ -28,15 +28,14 @@ pnpm add @prisma-next/extension-paradedb
|
|
|
28
28
|
|
|
29
29
|
## Usage
|
|
30
30
|
|
|
31
|
-
### Contract
|
|
31
|
+
### Contract definition
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
Author bm25 indexes via the standard `constraints.index(...)` surface; the registered `'bm25'` entry narrows `options` per-`type`:
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import { int4Column, textColumn
|
|
36
|
+
import { int4Column, textColumn } from '@prisma-next/adapter-postgres/column-types';
|
|
37
37
|
import sqlFamily from '@prisma-next/family-sql/pack';
|
|
38
38
|
import { defineContract, field, model } from '@prisma-next/sql-contract-ts/contract-builder';
|
|
39
|
-
import { bm25, bm25Index } from '@prisma-next/extension-paradedb/index-types';
|
|
40
39
|
import paradedb from '@prisma-next/extension-paradedb/pack';
|
|
41
40
|
import postgres from '@prisma-next/target-postgres/pack';
|
|
42
41
|
|
|
@@ -48,121 +47,40 @@ export const contract = defineContract({
|
|
|
48
47
|
Item: model('Item', {
|
|
49
48
|
fields: {
|
|
50
49
|
id: field.column(int4Column).id(),
|
|
51
|
-
|
|
52
|
-
category: field.column(textColumn),
|
|
53
|
-
rating: field.column(int4Column),
|
|
54
|
-
metadata: field.column(jsonbColumn),
|
|
50
|
+
body: field.column(textColumn),
|
|
55
51
|
},
|
|
56
|
-
}).sql({
|
|
52
|
+
}).sql(({ cols, constraints }) => ({
|
|
57
53
|
table: 'items',
|
|
58
54
|
indexes: [
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
bm25.text('category'),
|
|
64
|
-
bm25.numeric('rating'),
|
|
65
|
-
bm25.json('metadata', { tokenizer: 'ngram', min: 2, max: 3 }),
|
|
66
|
-
],
|
|
67
|
-
name: 'search_idx',
|
|
55
|
+
constraints.index([cols.body], {
|
|
56
|
+
name: 'item_body_bm25_idx',
|
|
57
|
+
type: 'bm25',
|
|
58
|
+
options: { key_field: 'id' },
|
|
68
59
|
}),
|
|
69
60
|
],
|
|
70
|
-
}),
|
|
61
|
+
})),
|
|
71
62
|
},
|
|
72
63
|
});
|
|
73
64
|
```
|
|
74
65
|
|
|
75
|
-
###
|
|
66
|
+
### key_field
|
|
76
67
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Builder | Description | Tokenizer support |
|
|
80
|
-
|---------|-------------|-------------------|
|
|
81
|
-
| `bm25.text(column, opts?)` | Text field (`text`, `varchar`) | Yes — any tokenizer + stemmer, remove_emojis |
|
|
82
|
-
| `bm25.numeric(column)` | Numeric field (filterable, sortable) | No |
|
|
83
|
-
| `bm25.boolean(column)` | Boolean field | No |
|
|
84
|
-
| `bm25.json(column, opts?)` | JSON/JSONB field | Yes — tokenizer + ngram params |
|
|
85
|
-
| `bm25.datetime(column)` | Timestamp/date field | No |
|
|
86
|
-
| `bm25.range(column)` | Range field | No |
|
|
87
|
-
| `bm25.expression(sql, opts)` | Raw SQL expression | Yes — `alias` required |
|
|
88
|
-
|
|
89
|
-
### Expression-Based Fields
|
|
90
|
-
|
|
91
|
-
For computed or JSON sub-field indexing, use `bm25.expression()` with a raw SQL string:
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
.index(
|
|
95
|
-
bm25Index({
|
|
96
|
-
keyField: 'id',
|
|
97
|
-
fields: [
|
|
98
|
-
bm25.text('description'),
|
|
99
|
-
bm25.expression("description || ' ' || category", {
|
|
100
|
-
alias: 'concat',
|
|
101
|
-
tokenizer: 'simple',
|
|
102
|
-
}),
|
|
103
|
-
bm25.expression("(metadata->>'color')", {
|
|
104
|
-
alias: 'meta_color',
|
|
105
|
-
tokenizer: 'ngram',
|
|
106
|
-
min: 2,
|
|
107
|
-
max: 3,
|
|
108
|
-
}),
|
|
109
|
-
],
|
|
110
|
-
}),
|
|
111
|
-
)
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### keyField Behavior
|
|
115
|
-
|
|
116
|
-
ParadeDB BM25 indexes require a `key_field` — a unique column that identifies each document:
|
|
117
|
-
|
|
118
|
-
- **Required**: Set `keyField` explicitly in `bm25Index(...)`.
|
|
119
|
-
- **Recommended**: Use the table primary key in most cases.
|
|
120
|
-
- **Override**: You can choose another unique column when needed.
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
.index(bm25Index({ keyField: 'id', fields: [bm25.text('body')] }))
|
|
124
|
-
.index(bm25Index({ keyField: 'uuid', fields: [bm25.text('body')] }))
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Tokenizers
|
|
128
|
-
|
|
129
|
-
All 12 built-in ParadeDB tokenizers are available via the `TokenizerId` type:
|
|
130
|
-
|
|
131
|
-
| Tokenizer | Description |
|
|
132
|
-
|-----------|-------------|
|
|
133
|
-
| `unicode_words` | Default. Unicode word boundaries (UAX #29). Lowercases. |
|
|
134
|
-
| `simple` | Splits on non-alphanumeric. Lowercases. |
|
|
135
|
-
| `ngram` | Character n-grams of configurable length. |
|
|
136
|
-
| `icu` | ICU Unicode standard segmentation. Multilingual. |
|
|
137
|
-
| `regex_pattern` | Regex-based tokenization. |
|
|
138
|
-
| `source_code` | camelCase / snake_case splitting. |
|
|
139
|
-
| `literal` | No splitting. Exact match, sort, aggregation. |
|
|
140
|
-
| `literal_normalized` | Literal + lowercase + token filters. |
|
|
141
|
-
| `whitespace` | Whitespace splitting + lowercase. |
|
|
142
|
-
| `chinese_compatible` | CJK-aware word segmentation. |
|
|
143
|
-
| `jieba` | Chinese segmentation via Jieba. |
|
|
144
|
-
| `lindera` | Japanese/Korean/Chinese via Lindera. |
|
|
68
|
+
ParadeDB BM25 indexes require a `key_field` — a unique column that identifies each document. It is required, must be a string, and is typically (but not always) the table's primary key.
|
|
145
69
|
|
|
146
70
|
## Capabilities
|
|
147
71
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
- `paradedb/bm25`: Indicates support for BM25 full-text search indexes
|
|
151
|
-
|
|
152
|
-
## Not Yet Implemented
|
|
72
|
+
- `paradedb/bm25` — indicates support for BM25 full-text search indexes
|
|
153
73
|
|
|
154
|
-
|
|
74
|
+
## Not yet implemented
|
|
155
75
|
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
- **Database dependencies**: `CREATE EXTENSION pg_search` via migration planner
|
|
76
|
+
- Per-column / per-expression tokenizer configuration (deferred to expression-index support)
|
|
77
|
+
- `@@@` operator and `pdb.*` query builder functions
|
|
78
|
+
- `CREATE EXTENSION pg_search` via migration planner
|
|
79
|
+
- Scoring, aggregation, and highlight functions
|
|
161
80
|
|
|
162
81
|
## References
|
|
163
82
|
|
|
164
83
|
- [ParadeDB documentation](https://docs.paradedb.com/)
|
|
165
84
|
- [ParadeDB CREATE INDEX](https://docs.paradedb.com/documentation/indexing/create-index)
|
|
166
|
-
- [
|
|
167
|
-
- [pg_search source](https://github.com/paradedb/paradedb/tree/main/pg_search)
|
|
85
|
+
- [ADR 210 — Index-type registry](../../../docs/architecture%20docs/adrs/ADR%20210%20-%20Index-type%20registry.md)
|
|
168
86
|
- [Prisma Next Architecture Overview](../../../docs/Architecture%20Overview.md)
|
package/dist/control.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as _$_prisma_next_sql_contract_index_types0 from "@prisma-next/sql-contract/index-types";
|
|
2
|
+
|
|
1
3
|
//#region src/core/descriptor-meta.d.ts
|
|
2
4
|
declare const paradedbPackMeta: {
|
|
3
5
|
readonly kind: "extension";
|
|
@@ -10,6 +12,11 @@ declare const paradedbPackMeta: {
|
|
|
10
12
|
readonly 'paradedb/bm25': true;
|
|
11
13
|
};
|
|
12
14
|
};
|
|
15
|
+
readonly indexTypes: _$_prisma_next_sql_contract_index_types0.IndexTypeBuilder<Record<never, never> & Record<"bm25", {
|
|
16
|
+
readonly options: {
|
|
17
|
+
key_field: string;
|
|
18
|
+
};
|
|
19
|
+
}>>;
|
|
13
20
|
};
|
|
14
21
|
//#endregion
|
|
15
22
|
export { paradedbPackMeta };
|
package/dist/control.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/descriptor-meta.ts"],"mappings":";;;cAGa,gBAAA;EAAA"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as paradedbPackMeta } from "./descriptor-meta-
|
|
1
|
+
import { t as paradedbPackMeta } from "./descriptor-meta-BF_fQseQ.mjs";
|
|
2
2
|
export { paradedbPackMeta };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as paradedbIndexTypes } from "./index-types-BWFfNqUb.mjs";
|
|
1
2
|
//#endregion
|
|
2
3
|
//#region src/core/descriptor-meta.ts
|
|
3
4
|
const paradedbPackMeta = {
|
|
@@ -6,9 +7,10 @@ const paradedbPackMeta = {
|
|
|
6
7
|
familyId: "sql",
|
|
7
8
|
targetId: "postgres",
|
|
8
9
|
version: "0.0.1",
|
|
9
|
-
capabilities: { postgres: { "paradedb/bm25": true } }
|
|
10
|
+
capabilities: { postgres: { "paradedb/bm25": true } },
|
|
11
|
+
indexTypes: paradedbIndexTypes
|
|
10
12
|
};
|
|
11
13
|
//#endregion
|
|
12
14
|
export { paradedbPackMeta as t };
|
|
13
15
|
|
|
14
|
-
//# sourceMappingURL=descriptor-meta-
|
|
16
|
+
//# sourceMappingURL=descriptor-meta-BF_fQseQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"descriptor-meta-BF_fQseQ.mjs","names":[],"sources":["../src/core/constants.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["/**\n * Extension ID for ParadeDB pg_search.\n */\nexport const PARADEDB_EXTENSION_ID = 'paradedb' as const;\n","import { paradedbIndexTypes } from '../types/index-types';\nimport { PARADEDB_EXTENSION_ID } from './constants';\n\nexport const paradedbPackMeta = {\n kind: 'extension',\n id: PARADEDB_EXTENSION_ID,\n familyId: 'sql',\n targetId: 'postgres',\n version: '0.0.1',\n capabilities: {\n postgres: {\n 'paradedb/bm25': true,\n },\n },\n indexTypes: paradedbIndexTypes,\n} as const;\n"],"mappings":";;;ACGA,MAAa,mBAAmB;CAC9B,MAAM;CACN,IAAI;CACJ,UAAU;CACV,UAAU;CACV,SAAS;CACT,cAAc,EACZ,UAAU,EACR,iBAAiB,MAClB,EACF;CACD,YAAY;CACb"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineIndexTypes } from "@prisma-next/sql-contract/index-types";
|
|
2
|
+
import { type } from "arktype";
|
|
3
|
+
//#region src/types/index-types.ts
|
|
4
|
+
const paradedbIndexTypes = defineIndexTypes().add("bm25", { options: type({
|
|
5
|
+
"+": "reject",
|
|
6
|
+
key_field: "string"
|
|
7
|
+
}) });
|
|
8
|
+
//#endregion
|
|
9
|
+
export { paradedbIndexTypes as t };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=index-types-BWFfNqUb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-types-BWFfNqUb.mjs","names":[],"sources":["../src/types/index-types.ts"],"sourcesContent":["import { defineIndexTypes } from '@prisma-next/sql-contract/index-types';\nimport { type } from 'arktype';\n\nexport const paradedbIndexTypes = defineIndexTypes().add('bm25', {\n options: type({\n '+': 'reject',\n key_field: 'string',\n }),\n});\n\nexport type IndexTypes = typeof paradedbIndexTypes.IndexTypes;\nexport type Bm25IndexOptions = IndexTypes['bm25']['options'];\n"],"mappings":";;;AAGA,MAAa,qBAAqB,kBAAkB,CAAC,IAAI,QAAQ,EAC/D,SAAS,KAAK;CACZ,KAAK;CACL,WAAW;CACZ,CAAC,EACH,CAAC"}
|
package/dist/index-types.d.mts
CHANGED
|
@@ -1,101 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as _$_prisma_next_sql_contract_index_types0 from "@prisma-next/sql-contract/index-types";
|
|
2
2
|
|
|
3
|
-
//#region src/core/constants.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Built-in ParadeDB tokenizer IDs.
|
|
6
|
-
* These correspond to the `pdb.*` casting syntax in `CREATE INDEX ... USING bm25`.
|
|
7
|
-
*/
|
|
8
|
-
type TokenizerId = 'unicode_words' | 'simple' | 'ngram' | 'icu' | 'regex_pattern' | 'source_code' | 'literal' | 'literal_normalized' | 'whitespace' | 'chinese_compatible' | 'jieba' | 'lindera';
|
|
9
|
-
//#endregion
|
|
10
3
|
//#region src/types/index-types.d.ts
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
readonly tokenizerParams?: Record<string, unknown>;
|
|
19
|
-
readonly alias?: string;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* BM25 field config for a SQL expression.
|
|
23
|
-
*/
|
|
24
|
-
type Bm25ExpressionFieldConfig = {
|
|
25
|
-
readonly expression: string;
|
|
26
|
-
readonly column?: never;
|
|
27
|
-
readonly alias: string;
|
|
28
|
-
readonly tokenizer?: string;
|
|
29
|
-
readonly tokenizerParams?: Record<string, unknown>;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* BM25 field config union.
|
|
33
|
-
*/
|
|
34
|
-
type Bm25FieldConfig = Bm25ColumnFieldConfig | Bm25ExpressionFieldConfig;
|
|
35
|
-
/**
|
|
36
|
-
* BM25 index configuration payload stored in `IndexDef.config`.
|
|
37
|
-
*/
|
|
38
|
-
type Bm25IndexConfig = {
|
|
39
|
-
readonly keyField: string;
|
|
40
|
-
readonly fields: readonly Bm25FieldConfig[];
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Options for a BM25 text field (text, varchar columns).
|
|
44
|
-
*/
|
|
45
|
-
type Bm25TextFieldOptions = {
|
|
46
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
47
|
-
readonly stemmer?: string;
|
|
48
|
-
readonly alias?: string;
|
|
49
|
-
readonly remove_emojis?: boolean;
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* Options for a BM25 JSON field (json, jsonb columns).
|
|
53
|
-
*/
|
|
54
|
-
type Bm25JsonFieldOptions = {
|
|
55
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
56
|
-
readonly alias?: string; /** Ngram-specific params when tokenizer is 'ngram'. */
|
|
57
|
-
readonly min?: number;
|
|
58
|
-
readonly max?: number;
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Options for a BM25 expression-based field.
|
|
62
|
-
*/
|
|
63
|
-
type Bm25ExpressionFieldOptions = {
|
|
64
|
-
readonly alias: string;
|
|
65
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
66
|
-
readonly min?: number;
|
|
67
|
-
readonly max?: number;
|
|
68
|
-
readonly stemmer?: string;
|
|
69
|
-
readonly pattern?: string;
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* Options for constructing a BM25 index definition.
|
|
73
|
-
*/
|
|
74
|
-
type Bm25IndexOptions = {
|
|
75
|
-
readonly keyField: string;
|
|
76
|
-
readonly fields: readonly Bm25FieldConfig[];
|
|
77
|
-
readonly name?: string;
|
|
78
|
-
};
|
|
79
|
-
/**
|
|
80
|
-
* Typed BM25 field builders.
|
|
81
|
-
* These produce `Bm25FieldConfig` objects for use in `bm25Index()`.
|
|
82
|
-
*/
|
|
83
|
-
declare const bm25: {
|
|
84
|
-
/** Text field with optional tokenizer config. */readonly text: (column: string, opts?: Bm25TextFieldOptions) => Bm25FieldConfig; /** Numeric field (filterable, sortable in BM25). */
|
|
85
|
-
readonly numeric: (column: string) => Bm25FieldConfig; /** Boolean field. */
|
|
86
|
-
readonly boolean: (column: string) => Bm25FieldConfig; /** JSON/JSONB field with optional tokenizer config. */
|
|
87
|
-
readonly json: (column: string, opts?: Bm25JsonFieldOptions) => Bm25FieldConfig; /** Datetime (timestamp/date) field. */
|
|
88
|
-
readonly datetime: (column: string) => Bm25FieldConfig; /** Range field. */
|
|
89
|
-
readonly range: (column: string) => Bm25FieldConfig; /** Raw SQL expression field. `alias` is required. */
|
|
90
|
-
readonly expression: (sql: string, opts: Bm25ExpressionFieldOptions) => Bm25FieldConfig;
|
|
91
|
-
};
|
|
92
|
-
/**
|
|
93
|
-
* Creates a generic index definition with a ParadeDB BM25 payload.
|
|
94
|
-
*
|
|
95
|
-
* `columns` only includes real table columns so core index validation remains
|
|
96
|
-
* target-agnostic. Expression fields stay in extension-owned `config.fields`.
|
|
97
|
-
*/
|
|
98
|
-
declare function bm25Index(opts: Bm25IndexOptions): IndexDef;
|
|
4
|
+
declare const paradedbIndexTypes: _$_prisma_next_sql_contract_index_types0.IndexTypeBuilder<Record<never, never> & Record<"bm25", {
|
|
5
|
+
readonly options: {
|
|
6
|
+
key_field: string;
|
|
7
|
+
};
|
|
8
|
+
}>>;
|
|
9
|
+
type IndexTypes = typeof paradedbIndexTypes.IndexTypes;
|
|
10
|
+
type Bm25IndexOptions = IndexTypes['bm25']['options'];
|
|
99
11
|
//#endregion
|
|
100
|
-
export { type
|
|
12
|
+
export { type Bm25IndexOptions, type IndexTypes, paradedbIndexTypes };
|
|
101
13
|
//# sourceMappingURL=index-types.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-types.d.mts","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"index-types.d.mts","names":[],"sources":["../src/types/index-types.ts"],"mappings":";;;cAGa,kBAAA,EAAkB,wCAAA,CAAA,gBAAA,CAAA,MAAA,iBAAA,MAAA;EAAA;;;;KAOnB,UAAA,UAAoB,kBAAA,CAAmB,UAAA;AAAA,KACvC,gBAAA,GAAmB,UAAA"}
|
package/dist/index-types.mjs
CHANGED
|
@@ -1,91 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Typed BM25 field builders.
|
|
4
|
-
* These produce `Bm25FieldConfig` objects for use in `bm25Index()`.
|
|
5
|
-
*/
|
|
6
|
-
const bm25 = {
|
|
7
|
-
/** Text field with optional tokenizer config. */
|
|
8
|
-
text(column, opts) {
|
|
9
|
-
return {
|
|
10
|
-
column,
|
|
11
|
-
...buildTokenizerConfig(opts?.tokenizer, {
|
|
12
|
-
stemmer: opts?.stemmer,
|
|
13
|
-
remove_emojis: opts?.remove_emojis
|
|
14
|
-
}),
|
|
15
|
-
...opts?.alias !== void 0 && { alias: opts.alias }
|
|
16
|
-
};
|
|
17
|
-
},
|
|
18
|
-
/** Numeric field (filterable, sortable in BM25). */
|
|
19
|
-
numeric(column) {
|
|
20
|
-
return { column };
|
|
21
|
-
},
|
|
22
|
-
/** Boolean field. */
|
|
23
|
-
boolean(column) {
|
|
24
|
-
return { column };
|
|
25
|
-
},
|
|
26
|
-
/** JSON/JSONB field with optional tokenizer config. */
|
|
27
|
-
json(column, opts) {
|
|
28
|
-
return {
|
|
29
|
-
column,
|
|
30
|
-
...buildTokenizerConfig(opts?.tokenizer, {
|
|
31
|
-
min: opts?.min,
|
|
32
|
-
max: opts?.max
|
|
33
|
-
}),
|
|
34
|
-
...opts?.alias !== void 0 && { alias: opts.alias }
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
/** Datetime (timestamp/date) field. */
|
|
38
|
-
datetime(column) {
|
|
39
|
-
return { column };
|
|
40
|
-
},
|
|
41
|
-
/** Range field. */
|
|
42
|
-
range(column) {
|
|
43
|
-
return { column };
|
|
44
|
-
},
|
|
45
|
-
/** Raw SQL expression field. `alias` is required. */
|
|
46
|
-
expression(sql, opts) {
|
|
47
|
-
return {
|
|
48
|
-
expression: sql,
|
|
49
|
-
alias: opts.alias,
|
|
50
|
-
...buildTokenizerConfig(opts.tokenizer, {
|
|
51
|
-
min: opts.min,
|
|
52
|
-
max: opts.max,
|
|
53
|
-
stemmer: opts.stemmer,
|
|
54
|
-
pattern: opts.pattern
|
|
55
|
-
})
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Creates a generic index definition with a ParadeDB BM25 payload.
|
|
61
|
-
*
|
|
62
|
-
* `columns` only includes real table columns so core index validation remains
|
|
63
|
-
* target-agnostic. Expression fields stay in extension-owned `config.fields`.
|
|
64
|
-
*/
|
|
65
|
-
function bm25Index(opts) {
|
|
66
|
-
return {
|
|
67
|
-
columns: opts.fields.flatMap((field) => "column" in field ? [field.column] : []),
|
|
68
|
-
...opts.name !== void 0 && { name: opts.name },
|
|
69
|
-
using: "bm25",
|
|
70
|
-
config: {
|
|
71
|
-
keyField: opts.keyField,
|
|
72
|
-
fields: opts.fields
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Builds `{ tokenizer, tokenizerParams? }` from a tokenizer ID and a bag of params.
|
|
78
|
-
* Filters out undefined values and omits `tokenizerParams` when empty.
|
|
79
|
-
*/
|
|
80
|
-
function buildTokenizerConfig(tokenizer, params) {
|
|
81
|
-
if (!tokenizer) return {};
|
|
82
|
-
const filtered = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== void 0));
|
|
83
|
-
return {
|
|
84
|
-
tokenizer,
|
|
85
|
-
...Object.keys(filtered).length > 0 && { tokenizerParams: filtered }
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
//#endregion
|
|
89
|
-
export { bm25, bm25Index };
|
|
90
|
-
|
|
91
|
-
//# sourceMappingURL=index-types.mjs.map
|
|
1
|
+
import { t as paradedbIndexTypes } from "./index-types-BWFfNqUb.mjs";
|
|
2
|
+
export { paradedbIndexTypes };
|
package/dist/pack.d.mts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as _$_prisma_next_sql_contract_index_types0 from "@prisma-next/sql-contract/index-types";
|
|
2
|
+
|
|
1
3
|
//#region src/exports/pack.d.ts
|
|
2
4
|
declare const paradedbPack: {
|
|
3
5
|
readonly kind: "extension";
|
|
@@ -10,6 +12,11 @@ declare const paradedbPack: {
|
|
|
10
12
|
readonly 'paradedb/bm25': true;
|
|
11
13
|
};
|
|
12
14
|
};
|
|
15
|
+
readonly indexTypes: _$_prisma_next_sql_contract_index_types0.IndexTypeBuilder<Record<never, never> & Record<"bm25", {
|
|
16
|
+
readonly options: {
|
|
17
|
+
key_field: string;
|
|
18
|
+
};
|
|
19
|
+
}>>;
|
|
13
20
|
};
|
|
14
21
|
//#endregion
|
|
15
22
|
export { paradedbPack as default };
|
package/dist/pack.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"mappings":";;;cAEM,YAAA;EAAA"}
|
package/dist/pack.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/extension-paradedb",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.82",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"
|
|
9
|
-
"@prisma-next/contract
|
|
8
|
+
"arktype": "^2.1.25",
|
|
9
|
+
"@prisma-next/sql-contract": "0.5.0-dev.82",
|
|
10
|
+
"@prisma-next/contract-authoring": "0.5.0-dev.82",
|
|
11
|
+
"@prisma-next/contract": "0.5.0-dev.82"
|
|
10
12
|
},
|
|
11
13
|
"devDependencies": {
|
|
12
14
|
"tsdown": "0.22.0",
|
|
13
15
|
"typescript": "5.9.3",
|
|
14
16
|
"vitest": "4.1.5",
|
|
15
|
-
"@prisma-next/
|
|
16
|
-
"@prisma-next/
|
|
17
|
+
"@prisma-next/tsconfig": "0.0.0",
|
|
18
|
+
"@prisma-next/tsdown": "0.0.0"
|
|
17
19
|
},
|
|
18
20
|
"files": [
|
|
19
21
|
"dist",
|
package/src/core/constants.ts
CHANGED
|
@@ -2,21 +2,3 @@
|
|
|
2
2
|
* Extension ID for ParadeDB pg_search.
|
|
3
3
|
*/
|
|
4
4
|
export const PARADEDB_EXTENSION_ID = 'paradedb' as const;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Built-in ParadeDB tokenizer IDs.
|
|
8
|
-
* These correspond to the `pdb.*` casting syntax in `CREATE INDEX ... USING bm25`.
|
|
9
|
-
*/
|
|
10
|
-
export type TokenizerId =
|
|
11
|
-
| 'unicode_words'
|
|
12
|
-
| 'simple'
|
|
13
|
-
| 'ngram'
|
|
14
|
-
| 'icu'
|
|
15
|
-
| 'regex_pattern'
|
|
16
|
-
| 'source_code'
|
|
17
|
-
| 'literal'
|
|
18
|
-
| 'literal_normalized'
|
|
19
|
-
| 'whitespace'
|
|
20
|
-
| 'chinese_compatible'
|
|
21
|
-
| 'jieba'
|
|
22
|
-
| 'lindera';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { paradedbIndexTypes } from '../types/index-types';
|
|
1
2
|
import { PARADEDB_EXTENSION_ID } from './constants';
|
|
2
3
|
|
|
3
4
|
export const paradedbPackMeta = {
|
|
@@ -11,4 +12,5 @@ export const paradedbPackMeta = {
|
|
|
11
12
|
'paradedb/bm25': true,
|
|
12
13
|
},
|
|
13
14
|
},
|
|
15
|
+
indexTypes: paradedbIndexTypes,
|
|
14
16
|
} as const;
|
|
@@ -1,12 +1,2 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export
|
|
3
|
-
Bm25ColumnFieldConfig,
|
|
4
|
-
Bm25ExpressionFieldConfig,
|
|
5
|
-
Bm25ExpressionFieldOptions,
|
|
6
|
-
Bm25FieldConfig,
|
|
7
|
-
Bm25IndexConfig,
|
|
8
|
-
Bm25IndexOptions,
|
|
9
|
-
Bm25JsonFieldOptions,
|
|
10
|
-
Bm25TextFieldOptions,
|
|
11
|
-
} from '../types/index-types';
|
|
12
|
-
export { bm25, bm25Index } from '../types/index-types';
|
|
1
|
+
export type { Bm25IndexOptions, IndexTypes } from '../types/index-types';
|
|
2
|
+
export { paradedbIndexTypes } from '../types/index-types';
|
package/src/types/index-types.ts
CHANGED
|
@@ -1,179 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* BM25 field config for a SQL expression.
|
|
17
|
-
*/
|
|
18
|
-
export type Bm25ExpressionFieldConfig = {
|
|
19
|
-
readonly expression: string;
|
|
20
|
-
readonly column?: never;
|
|
21
|
-
readonly alias: string;
|
|
22
|
-
readonly tokenizer?: string;
|
|
23
|
-
readonly tokenizerParams?: Record<string, unknown>;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* BM25 field config union.
|
|
28
|
-
*/
|
|
29
|
-
export type Bm25FieldConfig = Bm25ColumnFieldConfig | Bm25ExpressionFieldConfig;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* BM25 index configuration payload stored in `IndexDef.config`.
|
|
33
|
-
*/
|
|
34
|
-
export type Bm25IndexConfig = {
|
|
35
|
-
readonly keyField: string;
|
|
36
|
-
readonly fields: readonly Bm25FieldConfig[];
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Options for a BM25 text field (text, varchar columns).
|
|
41
|
-
*/
|
|
42
|
-
export type Bm25TextFieldOptions = {
|
|
43
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
44
|
-
readonly stemmer?: string;
|
|
45
|
-
readonly alias?: string;
|
|
46
|
-
readonly remove_emojis?: boolean;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Options for a BM25 JSON field (json, jsonb columns).
|
|
51
|
-
*/
|
|
52
|
-
export type Bm25JsonFieldOptions = {
|
|
53
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
54
|
-
readonly alias?: string;
|
|
55
|
-
/** Ngram-specific params when tokenizer is 'ngram'. */
|
|
56
|
-
readonly min?: number;
|
|
57
|
-
readonly max?: number;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Options for a BM25 expression-based field.
|
|
62
|
-
*/
|
|
63
|
-
export type Bm25ExpressionFieldOptions = {
|
|
64
|
-
readonly alias: string;
|
|
65
|
-
readonly tokenizer?: TokenizerId | (string & {});
|
|
66
|
-
readonly min?: number;
|
|
67
|
-
readonly max?: number;
|
|
68
|
-
readonly stemmer?: string;
|
|
69
|
-
readonly pattern?: string;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
type TokenizerConfig = {
|
|
73
|
-
readonly tokenizer?: string;
|
|
74
|
-
readonly tokenizerParams?: Record<string, unknown>;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Options for constructing a BM25 index definition.
|
|
79
|
-
*/
|
|
80
|
-
export type Bm25IndexOptions = {
|
|
81
|
-
readonly keyField: string;
|
|
82
|
-
readonly fields: readonly Bm25FieldConfig[];
|
|
83
|
-
readonly name?: string;
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Typed BM25 field builders.
|
|
88
|
-
* These produce `Bm25FieldConfig` objects for use in `bm25Index()`.
|
|
89
|
-
*/
|
|
90
|
-
export const bm25 = {
|
|
91
|
-
/** Text field with optional tokenizer config. */
|
|
92
|
-
text(column: string, opts?: Bm25TextFieldOptions): Bm25FieldConfig {
|
|
93
|
-
return {
|
|
94
|
-
column,
|
|
95
|
-
...buildTokenizerConfig(opts?.tokenizer, {
|
|
96
|
-
stemmer: opts?.stemmer,
|
|
97
|
-
remove_emojis: opts?.remove_emojis,
|
|
98
|
-
}),
|
|
99
|
-
...(opts?.alias !== undefined && { alias: opts.alias }),
|
|
100
|
-
};
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
/** Numeric field (filterable, sortable in BM25). */
|
|
104
|
-
numeric(column: string): Bm25FieldConfig {
|
|
105
|
-
return { column };
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
/** Boolean field. */
|
|
109
|
-
boolean(column: string): Bm25FieldConfig {
|
|
110
|
-
return { column };
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
/** JSON/JSONB field with optional tokenizer config. */
|
|
114
|
-
json(column: string, opts?: Bm25JsonFieldOptions): Bm25FieldConfig {
|
|
115
|
-
return {
|
|
116
|
-
column,
|
|
117
|
-
...buildTokenizerConfig(opts?.tokenizer, { min: opts?.min, max: opts?.max }),
|
|
118
|
-
...(opts?.alias !== undefined && { alias: opts.alias }),
|
|
119
|
-
};
|
|
120
|
-
},
|
|
121
|
-
|
|
122
|
-
/** Datetime (timestamp/date) field. */
|
|
123
|
-
datetime(column: string): Bm25FieldConfig {
|
|
124
|
-
return { column };
|
|
125
|
-
},
|
|
126
|
-
|
|
127
|
-
/** Range field. */
|
|
128
|
-
range(column: string): Bm25FieldConfig {
|
|
129
|
-
return { column };
|
|
130
|
-
},
|
|
131
|
-
|
|
132
|
-
/** Raw SQL expression field. `alias` is required. */
|
|
133
|
-
expression(sql: string, opts: Bm25ExpressionFieldOptions): Bm25FieldConfig {
|
|
134
|
-
return {
|
|
135
|
-
expression: sql,
|
|
136
|
-
alias: opts.alias,
|
|
137
|
-
...buildTokenizerConfig(opts.tokenizer, {
|
|
138
|
-
min: opts.min,
|
|
139
|
-
max: opts.max,
|
|
140
|
-
stemmer: opts.stemmer,
|
|
141
|
-
pattern: opts.pattern,
|
|
142
|
-
}),
|
|
143
|
-
};
|
|
144
|
-
},
|
|
145
|
-
} as const;
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Creates a generic index definition with a ParadeDB BM25 payload.
|
|
149
|
-
*
|
|
150
|
-
* `columns` only includes real table columns so core index validation remains
|
|
151
|
-
* target-agnostic. Expression fields stay in extension-owned `config.fields`.
|
|
152
|
-
*/
|
|
153
|
-
export function bm25Index(opts: Bm25IndexOptions): IndexDef {
|
|
154
|
-
return {
|
|
155
|
-
columns: opts.fields.flatMap((field) => ('column' in field ? [field.column] : [])),
|
|
156
|
-
...(opts.name !== undefined && { name: opts.name }),
|
|
157
|
-
using: 'bm25',
|
|
158
|
-
config: {
|
|
159
|
-
keyField: opts.keyField,
|
|
160
|
-
fields: opts.fields,
|
|
161
|
-
} satisfies Bm25IndexConfig,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Builds `{ tokenizer, tokenizerParams? }` from a tokenizer ID and a bag of params.
|
|
167
|
-
* Filters out undefined values and omits `tokenizerParams` when empty.
|
|
168
|
-
*/
|
|
169
|
-
function buildTokenizerConfig(
|
|
170
|
-
tokenizer: string | undefined,
|
|
171
|
-
params: Record<string, unknown>,
|
|
172
|
-
): TokenizerConfig {
|
|
173
|
-
if (!tokenizer) return {};
|
|
174
|
-
const filtered = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== undefined));
|
|
175
|
-
return {
|
|
176
|
-
tokenizer,
|
|
177
|
-
...(Object.keys(filtered).length > 0 && { tokenizerParams: filtered }),
|
|
178
|
-
};
|
|
179
|
-
}
|
|
1
|
+
import { defineIndexTypes } from '@prisma-next/sql-contract/index-types';
|
|
2
|
+
import { type } from 'arktype';
|
|
3
|
+
|
|
4
|
+
export const paradedbIndexTypes = defineIndexTypes().add('bm25', {
|
|
5
|
+
options: type({
|
|
6
|
+
'+': 'reject',
|
|
7
|
+
key_field: 'string',
|
|
8
|
+
}),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type IndexTypes = typeof paradedbIndexTypes.IndexTypes;
|
|
12
|
+
export type Bm25IndexOptions = IndexTypes['bm25']['options'];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"descriptor-meta-B6-NIHhB.mjs","names":[],"sources":["../src/core/constants.ts","../src/core/descriptor-meta.ts"],"sourcesContent":["/**\n * Extension ID for ParadeDB pg_search.\n */\nexport const PARADEDB_EXTENSION_ID = 'paradedb' as const;\n\n/**\n * Built-in ParadeDB tokenizer IDs.\n * These correspond to the `pdb.*` casting syntax in `CREATE INDEX ... USING bm25`.\n */\nexport type TokenizerId =\n | 'unicode_words'\n | 'simple'\n | 'ngram'\n | 'icu'\n | 'regex_pattern'\n | 'source_code'\n | 'literal'\n | 'literal_normalized'\n | 'whitespace'\n | 'chinese_compatible'\n | 'jieba'\n | 'lindera';\n","import { PARADEDB_EXTENSION_ID } from './constants';\n\nexport const paradedbPackMeta = {\n kind: 'extension',\n id: PARADEDB_EXTENSION_ID,\n familyId: 'sql',\n targetId: 'postgres',\n version: '0.0.1',\n capabilities: {\n postgres: {\n 'paradedb/bm25': true,\n },\n },\n} as const;\n"],"mappings":";;ACEA,MAAa,mBAAmB;CAC9B,MAAM;CACN,IAAI;CACJ,UAAU;CACV,UAAU;CACV,SAAS;CACT,cAAc,EACZ,UAAU,EACR,iBAAiB,MAClB,EACF;CACF"}
|
package/dist/index-types.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index-types.mjs","names":[],"sources":["../src/types/index-types.ts"],"sourcesContent":["import type { IndexDef } from '@prisma-next/contract-authoring';\nimport type { TokenizerId } from '../core/constants';\n\n/**\n * BM25 field config for a table column.\n */\nexport type Bm25ColumnFieldConfig = {\n readonly column: string;\n readonly expression?: never;\n readonly tokenizer?: string;\n readonly tokenizerParams?: Record<string, unknown>;\n readonly alias?: string;\n};\n\n/**\n * BM25 field config for a SQL expression.\n */\nexport type Bm25ExpressionFieldConfig = {\n readonly expression: string;\n readonly column?: never;\n readonly alias: string;\n readonly tokenizer?: string;\n readonly tokenizerParams?: Record<string, unknown>;\n};\n\n/**\n * BM25 field config union.\n */\nexport type Bm25FieldConfig = Bm25ColumnFieldConfig | Bm25ExpressionFieldConfig;\n\n/**\n * BM25 index configuration payload stored in `IndexDef.config`.\n */\nexport type Bm25IndexConfig = {\n readonly keyField: string;\n readonly fields: readonly Bm25FieldConfig[];\n};\n\n/**\n * Options for a BM25 text field (text, varchar columns).\n */\nexport type Bm25TextFieldOptions = {\n readonly tokenizer?: TokenizerId | (string & {});\n readonly stemmer?: string;\n readonly alias?: string;\n readonly remove_emojis?: boolean;\n};\n\n/**\n * Options for a BM25 JSON field (json, jsonb columns).\n */\nexport type Bm25JsonFieldOptions = {\n readonly tokenizer?: TokenizerId | (string & {});\n readonly alias?: string;\n /** Ngram-specific params when tokenizer is 'ngram'. */\n readonly min?: number;\n readonly max?: number;\n};\n\n/**\n * Options for a BM25 expression-based field.\n */\nexport type Bm25ExpressionFieldOptions = {\n readonly alias: string;\n readonly tokenizer?: TokenizerId | (string & {});\n readonly min?: number;\n readonly max?: number;\n readonly stemmer?: string;\n readonly pattern?: string;\n};\n\ntype TokenizerConfig = {\n readonly tokenizer?: string;\n readonly tokenizerParams?: Record<string, unknown>;\n};\n\n/**\n * Options for constructing a BM25 index definition.\n */\nexport type Bm25IndexOptions = {\n readonly keyField: string;\n readonly fields: readonly Bm25FieldConfig[];\n readonly name?: string;\n};\n\n/**\n * Typed BM25 field builders.\n * These produce `Bm25FieldConfig` objects for use in `bm25Index()`.\n */\nexport const bm25 = {\n /** Text field with optional tokenizer config. */\n text(column: string, opts?: Bm25TextFieldOptions): Bm25FieldConfig {\n return {\n column,\n ...buildTokenizerConfig(opts?.tokenizer, {\n stemmer: opts?.stemmer,\n remove_emojis: opts?.remove_emojis,\n }),\n ...(opts?.alias !== undefined && { alias: opts.alias }),\n };\n },\n\n /** Numeric field (filterable, sortable in BM25). */\n numeric(column: string): Bm25FieldConfig {\n return { column };\n },\n\n /** Boolean field. */\n boolean(column: string): Bm25FieldConfig {\n return { column };\n },\n\n /** JSON/JSONB field with optional tokenizer config. */\n json(column: string, opts?: Bm25JsonFieldOptions): Bm25FieldConfig {\n return {\n column,\n ...buildTokenizerConfig(opts?.tokenizer, { min: opts?.min, max: opts?.max }),\n ...(opts?.alias !== undefined && { alias: opts.alias }),\n };\n },\n\n /** Datetime (timestamp/date) field. */\n datetime(column: string): Bm25FieldConfig {\n return { column };\n },\n\n /** Range field. */\n range(column: string): Bm25FieldConfig {\n return { column };\n },\n\n /** Raw SQL expression field. `alias` is required. */\n expression(sql: string, opts: Bm25ExpressionFieldOptions): Bm25FieldConfig {\n return {\n expression: sql,\n alias: opts.alias,\n ...buildTokenizerConfig(opts.tokenizer, {\n min: opts.min,\n max: opts.max,\n stemmer: opts.stemmer,\n pattern: opts.pattern,\n }),\n };\n },\n} as const;\n\n/**\n * Creates a generic index definition with a ParadeDB BM25 payload.\n *\n * `columns` only includes real table columns so core index validation remains\n * target-agnostic. Expression fields stay in extension-owned `config.fields`.\n */\nexport function bm25Index(opts: Bm25IndexOptions): IndexDef {\n return {\n columns: opts.fields.flatMap((field) => ('column' in field ? [field.column] : [])),\n ...(opts.name !== undefined && { name: opts.name }),\n using: 'bm25',\n config: {\n keyField: opts.keyField,\n fields: opts.fields,\n } satisfies Bm25IndexConfig,\n };\n}\n\n/**\n * Builds `{ tokenizer, tokenizerParams? }` from a tokenizer ID and a bag of params.\n * Filters out undefined values and omits `tokenizerParams` when empty.\n */\nfunction buildTokenizerConfig(\n tokenizer: string | undefined,\n params: Record<string, unknown>,\n): TokenizerConfig {\n if (!tokenizer) return {};\n const filtered = Object.fromEntries(Object.entries(params).filter(([, v]) => v !== undefined));\n return {\n tokenizer,\n ...(Object.keys(filtered).length > 0 && { tokenizerParams: filtered }),\n };\n}\n"],"mappings":";;;;;AAyFA,MAAa,OAAO;;CAElB,KAAK,QAAgB,MAA8C;EACjE,OAAO;GACL;GACA,GAAG,qBAAqB,MAAM,WAAW;IACvC,SAAS,MAAM;IACf,eAAe,MAAM;IACtB,CAAC;GACF,GAAI,MAAM,UAAU,KAAA,KAAa,EAAE,OAAO,KAAK,OAAO;GACvD;;;CAIH,QAAQ,QAAiC;EACvC,OAAO,EAAE,QAAQ;;;CAInB,QAAQ,QAAiC;EACvC,OAAO,EAAE,QAAQ;;;CAInB,KAAK,QAAgB,MAA8C;EACjE,OAAO;GACL;GACA,GAAG,qBAAqB,MAAM,WAAW;IAAE,KAAK,MAAM;IAAK,KAAK,MAAM;IAAK,CAAC;GAC5E,GAAI,MAAM,UAAU,KAAA,KAAa,EAAE,OAAO,KAAK,OAAO;GACvD;;;CAIH,SAAS,QAAiC;EACxC,OAAO,EAAE,QAAQ;;;CAInB,MAAM,QAAiC;EACrC,OAAO,EAAE,QAAQ;;;CAInB,WAAW,KAAa,MAAmD;EACzE,OAAO;GACL,YAAY;GACZ,OAAO,KAAK;GACZ,GAAG,qBAAqB,KAAK,WAAW;IACtC,KAAK,KAAK;IACV,KAAK,KAAK;IACV,SAAS,KAAK;IACd,SAAS,KAAK;IACf,CAAC;GACH;;CAEJ;;;;;;;AAQD,SAAgB,UAAU,MAAkC;CAC1D,OAAO;EACL,SAAS,KAAK,OAAO,SAAS,UAAW,YAAY,QAAQ,CAAC,MAAM,OAAO,GAAG,EAAE,CAAE;EAClF,GAAI,KAAK,SAAS,KAAA,KAAa,EAAE,MAAM,KAAK,MAAM;EAClD,OAAO;EACP,QAAQ;GACN,UAAU,KAAK;GACf,QAAQ,KAAK;GACd;EACF;;;;;;AAOH,SAAS,qBACP,WACA,QACiB;CACjB,IAAI,CAAC,WAAW,OAAO,EAAE;CACzB,MAAM,WAAW,OAAO,YAAY,OAAO,QAAQ,OAAO,CAAC,QAAQ,GAAG,OAAO,MAAM,KAAA,EAAU,CAAC;CAC9F,OAAO;EACL;EACA,GAAI,OAAO,KAAK,SAAS,CAAC,SAAS,KAAK,EAAE,iBAAiB,UAAU;EACtE"}
|