graphile-search-plugin 1.1.1 → 3.0.0
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 +43 -23
- package/esm/index.d.ts +26 -0
- package/esm/index.js +23 -55
- package/esm/plugin.d.ts +44 -0
- package/esm/plugin.js +263 -0
- package/esm/preset.d.ts +25 -0
- package/esm/preset.js +29 -0
- package/esm/tsvector-codec.d.ts +29 -0
- package/esm/tsvector-codec.js +155 -0
- package/esm/types.d.ts +37 -0
- package/esm/types.js +6 -0
- package/index.d.ts +24 -8
- package/index.js +31 -57
- package/package.json +28 -14
- package/plugin.d.ts +44 -0
- package/plugin.js +267 -0
- package/preset.d.ts +25 -0
- package/preset.js +32 -0
- package/tsvector-codec.d.ts +29 -0
- package/tsvector-codec.js +162 -0
- package/types.d.ts +37 -0
- package/types.js +7 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TsvectorCodecPlugin
|
|
3
|
+
*
|
|
4
|
+
* Teaches PostGraphile v5 how to handle PostgreSQL's tsvector and tsquery types.
|
|
5
|
+
* Without this, tsvector columns are invisible to the schema builder and the
|
|
6
|
+
* search plugin cannot generate condition fields.
|
|
7
|
+
*
|
|
8
|
+
* This plugin:
|
|
9
|
+
* 1. Creates codecs for tsvector/tsquery via gather.hooks.pgCodecs_findPgCodec
|
|
10
|
+
* 2. Registers a custom "FullText" scalar type for tsvector columns
|
|
11
|
+
* 3. Maps tsvector codec to the FullText scalar (isolating filter operators)
|
|
12
|
+
* 4. Maps tsquery codec to GraphQL String
|
|
13
|
+
* 5. Optionally hides tsvector columns from output types
|
|
14
|
+
*/
|
|
15
|
+
import { GraphQLString } from 'graphql';
|
|
16
|
+
import sql from 'pg-sql2';
|
|
17
|
+
/**
|
|
18
|
+
* Creates a TsvectorCodecPlugin with the given options.
|
|
19
|
+
*
|
|
20
|
+
* @param options - Plugin configuration
|
|
21
|
+
* @returns GraphileConfig.Plugin
|
|
22
|
+
*/
|
|
23
|
+
export function createTsvectorCodecPlugin(options = {}) {
|
|
24
|
+
const { fullTextScalarName = 'FullText', hideTsvectorColumns = false, } = options;
|
|
25
|
+
return {
|
|
26
|
+
name: 'TsvectorCodecPlugin',
|
|
27
|
+
version: '1.0.0',
|
|
28
|
+
gather: {
|
|
29
|
+
hooks: {
|
|
30
|
+
async pgCodecs_findPgCodec(info, event) {
|
|
31
|
+
if (event.pgCodec) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const { pgType: type, serviceName } = event;
|
|
35
|
+
const pgCatalog = await info.helpers.pgIntrospection.getNamespaceByName(serviceName, 'pg_catalog');
|
|
36
|
+
if (!pgCatalog) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (type.typnamespace === pgCatalog._id && type.typname === 'tsvector') {
|
|
40
|
+
event.pgCodec = {
|
|
41
|
+
name: 'tsvector',
|
|
42
|
+
sqlType: sql.identifier('pg_catalog', 'tsvector'),
|
|
43
|
+
fromPg: (value) => value,
|
|
44
|
+
toPg: (value) => value,
|
|
45
|
+
attributes: undefined,
|
|
46
|
+
executor: null,
|
|
47
|
+
extensions: {
|
|
48
|
+
oid: type._id,
|
|
49
|
+
pg: {
|
|
50
|
+
serviceName,
|
|
51
|
+
schemaName: 'pg_catalog',
|
|
52
|
+
name: 'tsvector',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (type.typnamespace === pgCatalog._id && type.typname === 'tsquery') {
|
|
59
|
+
event.pgCodec = {
|
|
60
|
+
name: 'tsquery',
|
|
61
|
+
sqlType: sql.identifier('pg_catalog', 'tsquery'),
|
|
62
|
+
fromPg: (value) => value,
|
|
63
|
+
toPg: (value) => value,
|
|
64
|
+
attributes: undefined,
|
|
65
|
+
executor: null,
|
|
66
|
+
extensions: {
|
|
67
|
+
oid: type._id,
|
|
68
|
+
pg: {
|
|
69
|
+
serviceName,
|
|
70
|
+
schemaName: 'pg_catalog',
|
|
71
|
+
name: 'tsquery',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
schema: {
|
|
81
|
+
hooks: {
|
|
82
|
+
// Must run before PgCodecsPlugin's init (to avoid "unknown codec" warning)
|
|
83
|
+
// and before PgConnectionArgFilterPlugin's init (which creates filter
|
|
84
|
+
// types like FullTextFilter based on codec→GraphQL type mappings).
|
|
85
|
+
init: {
|
|
86
|
+
before: ['PgCodecs', 'PgConnectionArgFilterPlugin'],
|
|
87
|
+
callback(_, build) {
|
|
88
|
+
const { setGraphQLTypeForPgCodec } = build;
|
|
89
|
+
// Register a custom scalar type for tsvector columns.
|
|
90
|
+
// This ensures filter operators like `matches` only appear on
|
|
91
|
+
// tsvector filters, not on all String filters.
|
|
92
|
+
build.registerScalarType(fullTextScalarName, {}, () => ({
|
|
93
|
+
description: 'A full-text search tsvector value represented as a string.',
|
|
94
|
+
serialize(value) {
|
|
95
|
+
return String(value);
|
|
96
|
+
},
|
|
97
|
+
parseValue(value) {
|
|
98
|
+
if (typeof value === 'string') {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
throw new Error(`${fullTextScalarName} must be a string`);
|
|
102
|
+
},
|
|
103
|
+
parseLiteral(lit) {
|
|
104
|
+
if (lit.kind === 'NullValue')
|
|
105
|
+
return null;
|
|
106
|
+
if (lit.kind !== 'StringValue') {
|
|
107
|
+
throw new Error(`${fullTextScalarName} must be a string`);
|
|
108
|
+
}
|
|
109
|
+
return lit.value;
|
|
110
|
+
},
|
|
111
|
+
}), `TsvectorCodecPlugin registering ${fullTextScalarName} scalar`);
|
|
112
|
+
for (const codec of Object.values(build.input.pgRegistry.pgCodecs)) {
|
|
113
|
+
if (codec.name === 'tsvector') {
|
|
114
|
+
setGraphQLTypeForPgCodec(codec, 'input', fullTextScalarName);
|
|
115
|
+
setGraphQLTypeForPgCodec(codec, 'output', fullTextScalarName);
|
|
116
|
+
}
|
|
117
|
+
else if (codec.name === 'tsquery') {
|
|
118
|
+
setGraphQLTypeForPgCodec(codec, 'input', GraphQLString.name);
|
|
119
|
+
setGraphQLTypeForPgCodec(codec, 'output', GraphQLString.name);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return _;
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
...(hideTsvectorColumns
|
|
127
|
+
? {
|
|
128
|
+
entityBehavior: {
|
|
129
|
+
pgCodecAttribute: {
|
|
130
|
+
inferred: {
|
|
131
|
+
after: ['postInferred'],
|
|
132
|
+
provides: ['hideTsvectorColumns'],
|
|
133
|
+
callback(behavior, [codec, attributeName]) {
|
|
134
|
+
const attr = codec.attributes?.[attributeName];
|
|
135
|
+
if (attr?.codec?.name === 'tsvector') {
|
|
136
|
+
return [behavior, '-select'];
|
|
137
|
+
}
|
|
138
|
+
return behavior;
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
: {}),
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Default static instance using default options.
|
|
150
|
+
* Maps tsvector to the "FullText" scalar.
|
|
151
|
+
*/
|
|
152
|
+
export const TsvectorCodecPlugin = createTsvectorCodecPlugin();
|
|
153
|
+
export const TsvectorCodecPreset = {
|
|
154
|
+
plugins: [TsvectorCodecPlugin],
|
|
155
|
+
};
|
package/esm/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PgSearch Plugin Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the PostGraphile v5 search plugin configuration.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Plugin configuration options.
|
|
8
|
+
*/
|
|
9
|
+
export interface PgSearchPluginOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Prefix for tsvector condition fields.
|
|
12
|
+
* For example, with prefix 'fullText' and a column named 'tsv',
|
|
13
|
+
* the generated condition field will be 'fullTextTsv'.
|
|
14
|
+
* @default 'tsv'
|
|
15
|
+
*/
|
|
16
|
+
pgSearchPrefix?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to hide tsvector columns from output types.
|
|
19
|
+
* When true, tsvector columns won't appear as fields on the GraphQL object type.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
hideTsvectorColumns?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Name of the custom GraphQL scalar for tsvector columns.
|
|
25
|
+
* This scalar isolates filter operators (like `matches`) to tsvector columns
|
|
26
|
+
* rather than all String fields.
|
|
27
|
+
* @default 'FullText'
|
|
28
|
+
*/
|
|
29
|
+
fullTextScalarName?: string;
|
|
30
|
+
/**
|
|
31
|
+
* PostgreSQL text search configuration used with `websearch_to_tsquery`.
|
|
32
|
+
* Must match the configuration used when building your tsvector columns
|
|
33
|
+
* (e.g., `'english'`, `'simple'`, `'spanish'`).
|
|
34
|
+
* @default 'english'
|
|
35
|
+
*/
|
|
36
|
+
tsConfig?: string;
|
|
37
|
+
}
|
package/esm/types.js
ADDED
package/index.d.ts
CHANGED
|
@@ -1,10 +1,26 @@
|
|
|
1
|
-
export interface PgSearchPluginOptions {
|
|
2
|
-
/** Prefix for tsvector fields, default is 'tsv' */
|
|
3
|
-
pgSearchPrefix?: string;
|
|
4
|
-
}
|
|
5
1
|
/**
|
|
6
|
-
*
|
|
2
|
+
* PostGraphile v5 Search Plugin
|
|
3
|
+
*
|
|
4
|
+
* Provides full-text search capabilities for tsvector columns.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { PgSearchPlugin, PgSearchPreset } from 'graphile-search-plugin';
|
|
9
|
+
*
|
|
10
|
+
* // Option 1: Use the preset (recommended)
|
|
11
|
+
* const preset = {
|
|
12
|
+
* extends: [
|
|
13
|
+
* PgSearchPreset({
|
|
14
|
+
* pgSearchPrefix: 'fullText',
|
|
15
|
+
* }),
|
|
16
|
+
* ],
|
|
17
|
+
* };
|
|
18
|
+
*
|
|
19
|
+
* // Option 2: Use the plugin directly
|
|
20
|
+
* const plugin = PgSearchPlugin({ pgSearchPrefix: 'fullText' });
|
|
21
|
+
* ```
|
|
7
22
|
*/
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
23
|
+
export { PgSearchPlugin, createPgSearchPlugin } from './plugin';
|
|
24
|
+
export { PgSearchPreset } from './preset';
|
|
25
|
+
export { TsvectorCodecPlugin, TsvectorCodecPreset, createTsvectorCodecPlugin, } from './tsvector-codec';
|
|
26
|
+
export type { PgSearchPluginOptions } from './types';
|
package/index.js
CHANGED
|
@@ -1,60 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// plugins/PgSearchPlugin.ts
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.PgSearchPlugin = void 0;
|
|
5
2
|
/**
|
|
6
|
-
*
|
|
3
|
+
* PostGraphile v5 Search Plugin
|
|
4
|
+
*
|
|
5
|
+
* Provides full-text search capabilities for tsvector columns.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { PgSearchPlugin, PgSearchPreset } from 'graphile-search-plugin';
|
|
10
|
+
*
|
|
11
|
+
* // Option 1: Use the preset (recommended)
|
|
12
|
+
* const preset = {
|
|
13
|
+
* extends: [
|
|
14
|
+
* PgSearchPreset({
|
|
15
|
+
* pgSearchPrefix: 'fullText',
|
|
16
|
+
* }),
|
|
17
|
+
* ],
|
|
18
|
+
* };
|
|
19
|
+
*
|
|
20
|
+
* // Option 2: Use the plugin directly
|
|
21
|
+
* const plugin = PgSearchPlugin({ pgSearchPrefix: 'fullText' });
|
|
22
|
+
* ```
|
|
7
23
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const fieldName = inflection.camelCase(`${pgSearchPrefix}_${attr.name}`);
|
|
20
|
-
memo[fieldName] = fieldWithHooks(fieldName, { type: build.graphql.GraphQLString }, {});
|
|
21
|
-
return memo;
|
|
22
|
-
}, {}));
|
|
23
|
-
});
|
|
24
|
-
builder.hook('GraphQLObjectType:fields:field:args', (args, build, context) => {
|
|
25
|
-
const { pgSql: sql, inflection } = build;
|
|
26
|
-
const { scope: { isPgFieldConnection, isPgFieldSimpleCollection, pgFieldIntrospection: procOrTable, pgFieldIntrospectionTable: tableIfProc, }, addArgDataGenerator, } = context;
|
|
27
|
-
const table = tableIfProc || procOrTable;
|
|
28
|
-
if ((!isPgFieldConnection && !isPgFieldSimpleCollection) ||
|
|
29
|
-
!table ||
|
|
30
|
-
table.kind !== 'class') {
|
|
31
|
-
return args;
|
|
32
|
-
}
|
|
33
|
-
const tsvs = table.attributes.filter((attr) => attr.type.name === 'tsvector');
|
|
34
|
-
if (!tsvs.length)
|
|
35
|
-
return args;
|
|
36
|
-
tsvs.forEach((tsv) => {
|
|
37
|
-
const conditionFieldName = inflection.camelCase(`${pgSearchPrefix}_${tsv.name}`);
|
|
38
|
-
addArgDataGenerator(function addSearchCondition({ condition }) {
|
|
39
|
-
if (!condition || !(conditionFieldName in condition))
|
|
40
|
-
return {};
|
|
41
|
-
const value = condition[conditionFieldName];
|
|
42
|
-
if (value == null)
|
|
43
|
-
return {};
|
|
44
|
-
return {
|
|
45
|
-
pgQuery: (queryBuilder) => {
|
|
46
|
-
const tsquery = sql.fragment `websearch_to_tsquery('english', ${sql.value(value)})`;
|
|
47
|
-
const tableAlias = queryBuilder.getTableAlias();
|
|
48
|
-
// WHERE condition
|
|
49
|
-
queryBuilder.where(sql.fragment `${tableAlias}.${sql.identifier(tsv.name)} @@ ${tsquery}`);
|
|
50
|
-
// Automatically add ordering by relevance (descending)
|
|
51
|
-
queryBuilder.orderBy(sql.fragment `ts_rank(${tableAlias}.${sql.identifier(tsv.name)}, ${tsquery})`, false);
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
return args;
|
|
57
|
-
}, [], ['PgConnectionArgOrderBy']);
|
|
58
|
-
};
|
|
59
|
-
exports.PgSearchPlugin = PgSearchPlugin;
|
|
60
|
-
exports.default = PgSearchPlugin;
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.createTsvectorCodecPlugin = exports.TsvectorCodecPreset = exports.TsvectorCodecPlugin = exports.PgSearchPreset = exports.createPgSearchPlugin = exports.PgSearchPlugin = void 0;
|
|
26
|
+
var plugin_1 = require("./plugin");
|
|
27
|
+
Object.defineProperty(exports, "PgSearchPlugin", { enumerable: true, get: function () { return plugin_1.PgSearchPlugin; } });
|
|
28
|
+
Object.defineProperty(exports, "createPgSearchPlugin", { enumerable: true, get: function () { return plugin_1.createPgSearchPlugin; } });
|
|
29
|
+
var preset_1 = require("./preset");
|
|
30
|
+
Object.defineProperty(exports, "PgSearchPreset", { enumerable: true, get: function () { return preset_1.PgSearchPreset; } });
|
|
31
|
+
var tsvector_codec_1 = require("./tsvector-codec");
|
|
32
|
+
Object.defineProperty(exports, "TsvectorCodecPlugin", { enumerable: true, get: function () { return tsvector_codec_1.TsvectorCodecPlugin; } });
|
|
33
|
+
Object.defineProperty(exports, "TsvectorCodecPreset", { enumerable: true, get: function () { return tsvector_codec_1.TsvectorCodecPreset; } });
|
|
34
|
+
Object.defineProperty(exports, "createTsvectorCodecPlugin", { enumerable: true, get: function () { return tsvector_codec_1.createTsvectorCodecPlugin; } });
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "graphile-search-plugin",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Generate search conditions for your tsvector columns (PostGraphile v5)",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"homepage": "https://github.com/constructive-io/constructive",
|
|
7
7
|
"license": "MIT",
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
"types": "index.d.ts",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"clean": "makage clean",
|
|
13
|
-
"
|
|
14
|
-
"prepack": "pnpm run build",
|
|
13
|
+
"prepack": "npm run build",
|
|
15
14
|
"build": "makage build",
|
|
16
15
|
"build:dev": "makage build --dev",
|
|
17
16
|
"lint": "eslint . --fix",
|
|
@@ -33,22 +32,37 @@
|
|
|
33
32
|
"pgpm",
|
|
34
33
|
"plugin",
|
|
35
34
|
"postgres",
|
|
36
|
-
"graphql"
|
|
35
|
+
"graphql",
|
|
36
|
+
"search",
|
|
37
|
+
"tsvector",
|
|
38
|
+
"full-text-search"
|
|
37
39
|
],
|
|
38
40
|
"bugs": {
|
|
39
41
|
"url": "https://github.com/constructive-io/constructive/issues"
|
|
40
42
|
},
|
|
41
43
|
"devDependencies": {
|
|
42
|
-
"
|
|
43
|
-
"graphile-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"pgsql-test": "^3.1.1"
|
|
44
|
+
"@types/node": "^22.19.1",
|
|
45
|
+
"graphile-test": "^4.0.0",
|
|
46
|
+
"makage": "^0.1.10",
|
|
47
|
+
"pgsql-test": "^4.0.0",
|
|
48
|
+
"postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"
|
|
51
|
-
"
|
|
51
|
+
"@dataplan/pg": "1.0.0-rc.3",
|
|
52
|
+
"graphile-build": "^5.0.0-rc.3",
|
|
53
|
+
"graphile-build-pg": "^5.0.0-rc.3",
|
|
54
|
+
"graphile-config": "1.0.0-rc.3",
|
|
55
|
+
"pg-sql2": "^5.0.0-rc.3"
|
|
52
56
|
},
|
|
53
|
-
"
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"graphql": "^16.9.0",
|
|
59
|
+
"postgraphile": "^5.0.0-rc.4",
|
|
60
|
+
"postgraphile-plugin-connection-filter": "^3.0.0-rc.1"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"postgraphile-plugin-connection-filter": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"gitHead": "b2daeefe49cdefb3d01ea63cf778fb9b847ab5fe"
|
|
54
68
|
}
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostGraphile v5 Search Plugin
|
|
3
|
+
*
|
|
4
|
+
* Generates search condition fields for tsvector columns. When a search term
|
|
5
|
+
* is provided via the condition input, this plugin applies a
|
|
6
|
+
* `column @@ websearch_to_tsquery('english', $value)` WHERE clause and
|
|
7
|
+
* automatically orders results by `ts_rank` (descending) for relevance.
|
|
8
|
+
*
|
|
9
|
+
* Additionally provides:
|
|
10
|
+
* - `matches` filter operator for postgraphile-plugin-connection-filter
|
|
11
|
+
* - `fullTextRank` computed fields on output types (null when no search active)
|
|
12
|
+
* - `FULL_TEXT_RANK_ASC/DESC` orderBy enum values
|
|
13
|
+
*
|
|
14
|
+
* Uses the graphile-build hooks API to extend condition input types with
|
|
15
|
+
* search fields for each tsvector column found on a table's codec.
|
|
16
|
+
*
|
|
17
|
+
* ARCHITECTURE NOTE:
|
|
18
|
+
* Condition field apply functions run during a deferred phase (SQL generation)
|
|
19
|
+
* on a queryBuilder proxy — NOT on the real PgSelectStep. The rank field plan
|
|
20
|
+
* runs earlier, during Grafast's planning phase, on the real PgSelectStep.
|
|
21
|
+
*
|
|
22
|
+
* To bridge these two phases we use a module-level WeakMap keyed by the SQL
|
|
23
|
+
* alias object (shared between proxy and PgSelectStep via reference identity).
|
|
24
|
+
*
|
|
25
|
+
* The rank field plan creates a `lambda` step that reads the row tuple at a
|
|
26
|
+
* dynamically-determined index. The condition apply adds `ts_rank(...)` to
|
|
27
|
+
* the SQL SELECT list via `proxy.selectAndReturnIndex()` and stores the
|
|
28
|
+
* resulting index in the WeakMap slot. At execution time the lambda reads
|
|
29
|
+
* the rank value from that index.
|
|
30
|
+
*/
|
|
31
|
+
import 'graphile-build';
|
|
32
|
+
import 'graphile-build-pg';
|
|
33
|
+
import type { GraphileConfig } from 'graphile-config';
|
|
34
|
+
import type { PgSearchPluginOptions } from './types';
|
|
35
|
+
/**
|
|
36
|
+
* Creates the search plugin with the given options.
|
|
37
|
+
*/
|
|
38
|
+
export declare function createPgSearchPlugin(options?: PgSearchPluginOptions): GraphileConfig.Plugin;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a PgSearchPlugin with the given options.
|
|
41
|
+
* This is the main entry point for using the plugin.
|
|
42
|
+
*/
|
|
43
|
+
export declare const PgSearchPlugin: typeof createPgSearchPlugin;
|
|
44
|
+
export default PgSearchPlugin;
|