@prisma/orm-sqlite 8.0.0-rc.11-dev.52 → 8.0.0-rc.11-dev.54
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/dist/config.mjs
CHANGED
|
@@ -9,8 +9,21 @@ import sqlite, { sqliteCreateNamespace } from "@prisma/orm-target-sqlite/target/
|
|
|
9
9
|
import sqlitePackRef from "@prisma/orm-target-sqlite/target/pack";
|
|
10
10
|
import { ifDefined } from "@prisma/orm-framework/utils/defined";
|
|
11
11
|
import { extname, join } from "pathe";
|
|
12
|
+
import { isDynamicPattern } from "tinyglobby";
|
|
12
13
|
//#region ../../../3-extensions/sqlite/dist/config.mjs
|
|
14
|
+
function staticPrefixDirectory(pattern) {
|
|
15
|
+
const staticSegments = [];
|
|
16
|
+
for (const segment of pattern.replaceAll("\\", "/").split("/")) {
|
|
17
|
+
if (isDynamicPattern(segment)) break;
|
|
18
|
+
staticSegments.push(segment);
|
|
19
|
+
}
|
|
20
|
+
return staticSegments.join("/");
|
|
21
|
+
}
|
|
13
22
|
function deriveOutputPath(contractPath) {
|
|
23
|
+
if (isDynamicPattern(contractPath)) {
|
|
24
|
+
const prefix = staticPrefixDirectory(contractPath);
|
|
25
|
+
return prefix.length === 0 ? "contract.json" : `${prefix}/contract.json`;
|
|
26
|
+
}
|
|
14
27
|
const ext = extname(contractPath);
|
|
15
28
|
if (ext.length === 0) return `${contractPath}.json`;
|
|
16
29
|
return `${contractPath.slice(0, -ext.length)}.json`;
|
package/dist/config.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.mjs","names":[],"sources":["../../../../3-extensions/sqlite/dist/config.mjs"],"sourcesContent":["import sqliteAdapter from \"@internal/adapter-sqlite/control\";\nimport { defineConfig as defineConfig$1 } from \"@internal/config/config-types\";\nimport sqliteDriver from \"@internal/driver-sqlite/control\";\nimport sql from \"@internal/family-sql/control\";\nimport { prismaContract } from \"@internal/sql-contract-psl/provider\";\nimport { typescriptContractFromPath } from \"@internal/sql-contract-ts/config-types\";\nimport { SQLITE_INTEGER_CODEC_ID, SQLITE_TEXT_CODEC_ID } from \"@internal/target-sqlite/codec-ids\";\nimport sqlite, { sqliteCreateNamespace } from \"@internal/target-sqlite/control\";\nimport sqlitePackRef from \"@internal/target-sqlite/pack\";\nimport { ifDefined } from \"@internal/utils/defined\";\nimport { extname, join } from \"pathe\";\n//#region src/config/define-config.ts\nfunction deriveOutputPath(contractPath) {\n\tconst ext = extname(contractPath);\n\tif (ext.length === 0) return `${contractPath}.json`;\n\treturn `${contractPath.slice(0, -ext.length)}.json`;\n}\nfunction defineConfig(options) {\n\tconst extensions = options.extensions ?? [];\n\tconst output = options.output !== void 0 ? join(options.output, \"contract.json\") : deriveOutputPath(options.contract);\n\treturn defineConfig$1({\n\t\tfamily: sql,\n\t\ttarget: sqlite,\n\t\tadapter: sqliteAdapter,\n\t\tdriver: sqliteDriver,\n\t\textensions,\n\t\tcontract: extname(options.contract) === \".ts\" ? typescriptContractFromPath(options.contract, output) : prismaContract(options.contract, {\n\t\t\toutput,\n\t\t\ttarget: sqlitePackRef,\n\t\t\tcreateNamespace: sqliteCreateNamespace,\n\t\t\tenumInferenceCodecs: {\n\t\t\t\ttext: SQLITE_TEXT_CODEC_ID,\n\t\t\t\tint: SQLITE_INTEGER_CODEC_ID\n\t\t\t}\n\t\t}),\n\t\t...ifDefined(\"db\", options.db),\n\t\t...ifDefined(\"migrations\", options.migrations)\n\t});\n}\n//#endregion\nexport { defineConfig };\n\n//# sourceMappingURL=config.mjs.map"],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.mjs","names":[],"sources":["../../../../3-extensions/sqlite/dist/config.mjs"],"sourcesContent":["import sqliteAdapter from \"@internal/adapter-sqlite/control\";\nimport { defineConfig as defineConfig$1 } from \"@internal/config/config-types\";\nimport sqliteDriver from \"@internal/driver-sqlite/control\";\nimport sql from \"@internal/family-sql/control\";\nimport { prismaContract } from \"@internal/sql-contract-psl/provider\";\nimport { typescriptContractFromPath } from \"@internal/sql-contract-ts/config-types\";\nimport { SQLITE_INTEGER_CODEC_ID, SQLITE_TEXT_CODEC_ID } from \"@internal/target-sqlite/codec-ids\";\nimport sqlite, { sqliteCreateNamespace } from \"@internal/target-sqlite/control\";\nimport sqlitePackRef from \"@internal/target-sqlite/pack\";\nimport { ifDefined } from \"@internal/utils/defined\";\nimport { extname, join } from \"pathe\";\nimport { isDynamicPattern } from \"tinyglobby\";\n//#region src/config/define-config.ts\nfunction staticPrefixDirectory(pattern) {\n\tconst staticSegments = [];\n\tfor (const segment of pattern.replaceAll(\"\\\\\", \"/\").split(\"/\")) {\n\t\tif (isDynamicPattern(segment)) break;\n\t\tstaticSegments.push(segment);\n\t}\n\treturn staticSegments.join(\"/\");\n}\nfunction deriveOutputPath(contractPath) {\n\tif (isDynamicPattern(contractPath)) {\n\t\tconst prefix = staticPrefixDirectory(contractPath);\n\t\treturn prefix.length === 0 ? \"contract.json\" : `${prefix}/contract.json`;\n\t}\n\tconst ext = extname(contractPath);\n\tif (ext.length === 0) return `${contractPath}.json`;\n\treturn `${contractPath.slice(0, -ext.length)}.json`;\n}\nfunction defineConfig(options) {\n\tconst extensions = options.extensions ?? [];\n\tconst output = options.output !== void 0 ? join(options.output, \"contract.json\") : deriveOutputPath(options.contract);\n\treturn defineConfig$1({\n\t\tfamily: sql,\n\t\ttarget: sqlite,\n\t\tadapter: sqliteAdapter,\n\t\tdriver: sqliteDriver,\n\t\textensions,\n\t\tcontract: extname(options.contract) === \".ts\" ? typescriptContractFromPath(options.contract, output) : prismaContract(options.contract, {\n\t\t\toutput,\n\t\t\ttarget: sqlitePackRef,\n\t\t\tcreateNamespace: sqliteCreateNamespace,\n\t\t\tenumInferenceCodecs: {\n\t\t\t\ttext: SQLITE_TEXT_CODEC_ID,\n\t\t\t\tint: SQLITE_INTEGER_CODEC_ID\n\t\t\t}\n\t\t}),\n\t\t...ifDefined(\"db\", options.db),\n\t\t...ifDefined(\"migrations\", options.migrations)\n\t});\n}\n//#endregion\nexport { defineConfig };\n\n//# sourceMappingURL=config.mjs.map"],"mappings":";;;;;;;;;;;;;AAaA,SAAS,sBAAsB,SAAS;CACvC,MAAM,iBAAiB,CAAC;CACxB,KAAK,MAAM,WAAW,QAAQ,WAAW,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,GAAG;EAC/D,IAAI,iBAAiB,OAAO,GAAG;EAC/B,eAAe,KAAK,OAAO;CAC5B;CACA,OAAO,eAAe,KAAK,GAAG;AAC/B;AACA,SAAS,iBAAiB,cAAc;CACvC,IAAI,iBAAiB,YAAY,GAAG;EACnC,MAAM,SAAS,sBAAsB,YAAY;EACjD,OAAO,OAAO,WAAW,IAAI,kBAAkB,GAAG,OAAO;CAC1D;CACA,MAAM,MAAM,QAAQ,YAAY;CAChC,IAAI,IAAI,WAAW,GAAG,OAAO,GAAG,aAAa;CAC7C,OAAO,GAAG,aAAa,MAAM,GAAG,CAAC,IAAI,MAAM,EAAE;AAC9C;AACA,SAAS,aAAa,SAAS;CAC9B,MAAM,aAAa,QAAQ,cAAc,CAAC;CAC1C,MAAM,SAAS,QAAQ,WAAW,KAAK,IAAI,KAAK,QAAQ,QAAQ,eAAe,IAAI,iBAAiB,QAAQ,QAAQ;CACpH,OAAO,eAAe;EACrB,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,QAAQ;EACR;EACA,UAAU,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,2BAA2B,QAAQ,UAAU,MAAM,IAAI,eAAe,QAAQ,UAAU;GACvI;GACA,QAAQ;GACR,iBAAiB;GACjB,qBAAqB;IACpB,MAAM;IACN,KAAK;GACN;EACD,CAAC;EACD,GAAG,UAAU,MAAM,QAAQ,EAAE;EAC7B,GAAG,UAAU,cAAc,QAAQ,UAAU;CAC9C,CAAC;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/orm-sqlite",
|
|
3
|
-
"version": "8.0.0-rc.11-dev.
|
|
3
|
+
"version": "8.0.0-rc.11-dev.54",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -10,16 +10,17 @@
|
|
|
10
10
|
"skills"
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@prisma/orm-family-sql": "8.0.0-rc.11-dev.
|
|
14
|
-
"@prisma/orm-framework": "8.0.0-rc.11-dev.
|
|
15
|
-
"@prisma/orm-target-sqlite": "8.0.0-rc.11-dev.
|
|
16
|
-
"@prisma/orm-toolchain": "8.0.0-rc.11-dev.
|
|
17
|
-
"pathe": "^2.0.3"
|
|
13
|
+
"@prisma/orm-family-sql": "8.0.0-rc.11-dev.54",
|
|
14
|
+
"@prisma/orm-framework": "8.0.0-rc.11-dev.54",
|
|
15
|
+
"@prisma/orm-target-sqlite": "8.0.0-rc.11-dev.54",
|
|
16
|
+
"@prisma/orm-toolchain": "8.0.0-rc.11-dev.54",
|
|
17
|
+
"pathe": "^2.0.3",
|
|
18
|
+
"tinyglobby": "^0.2.17"
|
|
18
19
|
},
|
|
19
20
|
"devDependencies": {
|
|
20
|
-
"@internal/sqlite": "8.0.0-rc.11-dev.
|
|
21
|
-
"@repo/tsconfig": "8.0.0-rc.11-dev.
|
|
22
|
-
"@repo/tsdown": "8.0.0-rc.11-dev.
|
|
21
|
+
"@internal/sqlite": "8.0.0-rc.11-dev.54",
|
|
22
|
+
"@repo/tsconfig": "8.0.0-rc.11-dev.54",
|
|
23
|
+
"@repo/tsdown": "8.0.0-rc.11-dev.54",
|
|
23
24
|
"tsdown": "0.22.14",
|
|
24
25
|
"typescript": "5.9.3"
|
|
25
26
|
},
|
package/skills/prisma-8/SKILL.md
CHANGED
|
@@ -134,7 +134,7 @@ Then run `pnpm prisma contract emit` (or rely on the Vite plugin — see `refere
|
|
|
134
134
|
@@fullTextIndex([text], where: "archived_at IS NULL", name: "message_text_search_live")
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
The TS builder has the same helper: `fullTextIndex(cols.text, { name: 'message_text_search' })`, from `@prisma/orm-postgres/contract-builder`, inside the model's `sql({ indexes: [...] })`. It takes exactly one field, an optional `language` (default `english`, from the same allowlist the operations accept), an optional `where:` for a partial index, and `name:` xor `map:` like any expression index. It is repeatable, so a model may index several columns. Give the index and the operation the same `language` — a mismatch is silent, costing the index and falling back to a sequential scan. It lowers to a GIN index over `to_tsvector('<language>', "<column>")` — the column name resolved through `@map` — so `@@index(expression: …)` remains only for expressions this attribute does not cover.
|
|
137
|
+
The TS builder has the same helper: `fullTextIndex(cols.text, { name: 'message_text_search' })`, from `@prisma/orm-postgres/contract-builder`, inside the model's `sql({ indexes: [...] })`. It takes exactly one field, an optional `language` (default `english`, from the same allowlist the operations accept), an optional `where:` for a partial index, and `name:` xor `map:` like any expression index. It is repeatable, so a model may index several columns. Give the index and the operation the same `language` — a mismatch is silent, costing the index and falling back to a sequential scan. The parser that builds the query (`websearchToTsquery` and the others) takes its own `language` for the query side; it does not affect index use. It lowers to a GIN index over `to_tsvector('<language>', "<column>")` — the column name resolved through `@map` — so `@@index(expression: …)` remains only for expressions this attribute does not cover.
|
|
138
138
|
|
|
139
139
|
PSL alias surface for repeated types lives in a top-level `types {}` block:
|
|
140
140
|
|
|
@@ -62,24 +62,41 @@ db.orm.public.User.where({ kind: 'admin' });
|
|
|
62
62
|
|
|
63
63
|
Operators on the field proxy include `.eq`, `.neq`, `.lt`, `.lte`, `.gt`, `.gte`, `.like`, `.ilike`, `.in([...])`, `.isNull()`, `.isNotNull()`. Extensions add target-specific operators on extension-typed columns (`pgvector`'s `.cosineDistance(...)`, `postgis`'s `.within(...)` / `.intersectsBbox(...)` / `.distanceSphere(...)`).
|
|
64
64
|
|
|
65
|
-
**Full-text search** is built into the Postgres target, on any text column: `.fullTextMatches(q)` is the predicate, `.fullTextRank(q)` scores a row so you can order by relevance, and `.fullTextHeadline(q)` returns the text with `<b>` around the matches. The
|
|
65
|
+
**Full-text search** is built into the Postgres target, on any text column: `.fullTextMatches(q)` is the predicate, `.fullTextRank(q)` scores a row so you can order by relevance, and `.fullTextHeadline(q)` returns the text with `<b>` around the matches. The argument `q` is a `tsquery`, built with a helper from `@prisma/orm-postgres/target/full-text`. A bare string is a type error, because Postgres would read it as `tsquery` syntax without lowercasing or stemming it. Pick the helper by where the text comes from:
|
|
66
|
+
|
|
67
|
+
- A search box: `websearchToTsquery(input)`. `"an exact phrase"`, `-excluded` and `or` work, and it never errors. `plaintoTsquery` requires every word; `phrasetoTsquery` requires the words in order.
|
|
68
|
+
- User input inside operator syntax, such as typeahead: the `tsquery` tag, `` tsquery`${term}:*` ``. The literal parts are trusted `tsquery` syntax you write. Each interpolated value becomes exactly one quoted term, so user input cannot add operators or break the syntax; an empty value adds no words, like a stop word. A value with several words becomes a phrase: `` tsquery`${'new y'}:*` `` gives `'new':* <-> 'y':*`, so the words must be adjacent and in order, and `:*` applies to each word. Do not put quotes around the interpolation yourself: `` tsquery`'${term}':*` `` is a syntax error for every input. Postgres `to_tsquery` then lowercases and stems every word. `` tsquery({ language: 'german' })`...` `` picks the configuration.
|
|
69
|
+
- Operator syntax you write in full: `toTsquery("'zebra' & !'graze'")`. Malformed text fails at execution, so never pass user input to it; use the `tsquery` tag for that.
|
|
70
|
+
|
|
71
|
+
The four parsers are also `fns` members in the SQL builder. Each takes the text (a string, or a text column of any kind, `varchar` included) and `{ language? }`, and binds the text as a parameter. The `tsquery` tag is an import in both the ORM and the SQL builder. A `tsquery` value read back from a query can be passed straight back as the query.
|
|
72
|
+
|
|
73
|
+
Each operation takes an options object as its second argument. `language` (default `'english'`) is the configuration for the column's `to_tsvector`, the expression the index covers; the parser's or tag's own `language` governs the query side, and the two normally match. It only accepts the configurations a stock PostgreSQL server ships with (`'simple'`, `'german'`, `'french'`, …); `fullTextRank` also takes `normalization` (the `ts_rank` bitmask, 0 to 63) and `coverDensity` (for `ts_rank_cd`); `fullTextHeadline` also takes `startSel`, `stopSel`, `maxWords`, `minWords` and `highlightAll`. Every one of them is written into the SQL as a literal, so anything invalid throws `RUNTIME.ARGUMENT_INVALID` when the query is built.
|
|
66
74
|
|
|
67
75
|
```typescript
|
|
68
|
-
|
|
76
|
+
import { tsquery, websearchToTsquery } from '@prisma/orm-postgres/target/full-text';
|
|
77
|
+
|
|
78
|
+
// ORM: filter by the search-box query, order by relevance. Build the query once and reuse it.
|
|
79
|
+
const q = websearchToTsquery(query);
|
|
69
80
|
const hits = await db.orm.public.Message
|
|
70
81
|
.select('id', 'text')
|
|
71
|
-
.where((m) => m.text.fullTextMatches(
|
|
72
|
-
.orderBy((m) => m.text.fullTextRank(
|
|
82
|
+
.where((m) => m.text.fullTextMatches(q))
|
|
83
|
+
.orderBy((m) => m.text.fullTextRank(q).desc())
|
|
73
84
|
.limit(20)
|
|
74
85
|
.all();
|
|
75
86
|
|
|
76
|
-
//
|
|
87
|
+
// ORM: typeahead, the typed text as a prefix term.
|
|
88
|
+
const suggestions = await db.orm.public.Message
|
|
89
|
+
.select('id', 'text')
|
|
90
|
+
.where((m) => m.text.fullTextMatches(tsquery`${term}:*`))
|
|
91
|
+
.all();
|
|
92
|
+
|
|
93
|
+
// SQL builder: the same query filters and highlights, so the snippet marks what selected the row.
|
|
77
94
|
const snippets = db.sql.public.message
|
|
78
95
|
.select('id')
|
|
79
96
|
.select('snippet', (f, fns) =>
|
|
80
|
-
fns.fullTextHeadline(f.text,
|
|
97
|
+
fns.fullTextHeadline(f.text, q, { startSel: '<mark>', stopSel: '</mark>', maxWords: 20 }),
|
|
81
98
|
)
|
|
82
|
-
.where((f, fns) => fns.fullTextMatches(f.text,
|
|
99
|
+
.where((f, fns) => fns.fullTextMatches(f.text, q))
|
|
83
100
|
.build();
|
|
84
101
|
```
|
|
85
102
|
|