@palbase/backend 22.0.1 → 22.1.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/dist/bin/palbase-backend.cjs +340 -22
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +2 -2
- package/dist/{chunk-QYOHMVUW.js → chunk-74XDEF5J.js} +338 -22
- package/dist/chunk-74XDEF5J.js.map +1 -0
- package/dist/{chunk-SSGAMC26.js → chunk-I3ON7MYF.js} +57 -5
- package/dist/chunk-I3ON7MYF.js.map +1 -0
- package/dist/{chunk-POYAFBLF.js → chunk-SQC5EIWY.js} +5 -3
- package/dist/chunk-SQC5EIWY.js.map +1 -0
- package/dist/db/index.cjs +60 -6
- package/dist/db/index.cjs.map +1 -1
- package/dist/db/index.d.cts +2 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +7 -3
- package/dist/{endpoint-B0LpZixz.d.cts → endpoint-BVT6jcVW.d.cts} +39 -7
- package/dist/{endpoint-B0LpZixz.d.ts → endpoint-BVT6jcVW.d.ts} +39 -7
- package/dist/engine/index.cjs +340 -22
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +4 -4
- package/dist/engine/index.d.ts +4 -4
- package/dist/engine/index.js +2 -2
- package/dist/{index-B4W6d2VJ.d.cts → index-BS1gW4nV.d.cts} +24 -25
- package/dist/{index-BGSCWlUa.d.cts → index-BqCiHao8.d.cts} +97 -7
- package/dist/{index-BCNtlG1w.d.ts → index-CCZqzych.d.ts} +24 -25
- package/dist/{index-g-EzitI-.d.ts → index-vwHoS0l2.d.ts} +97 -7
- package/dist/index.cjs +244 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -9
- package/dist/index.d.ts +124 -9
- package/dist/index.js +186 -3
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{registry-Cw0YEYCg.d.cts → registry-BWttGlaT.d.cts} +1 -1
- package/dist/{registry-3BLYv4si.d.ts → registry-Bsuf-orT.d.ts} +1 -1
- package/docs/endpoints.md +1 -1
- package/docs/errors.md +9 -0
- package/docs/llms-full.txt +10 -1
- package/package.json +2 -2
- package/dist/chunk-POYAFBLF.js.map +0 -1
- package/dist/chunk-QYOHMVUW.js.map +0 -1
- package/dist/chunk-SSGAMC26.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -97,6 +97,7 @@ __export(src_exports, {
|
|
|
97
97
|
buildModuleClients: () => buildModuleClients,
|
|
98
98
|
buildProvider: () => buildProvider,
|
|
99
99
|
dec: () => dec,
|
|
100
|
+
defineChannels: () => defineChannels,
|
|
100
101
|
defineEgress: () => defineEgress,
|
|
101
102
|
defineError: () => defineError,
|
|
102
103
|
defineFlags: () => defineFlags,
|
|
@@ -126,8 +127,11 @@ __export(src_exports, {
|
|
|
126
127
|
makeTypedDB: () => makeTypedDB,
|
|
127
128
|
now: () => now,
|
|
128
129
|
numeric: () => numeric,
|
|
130
|
+
openai: () => openai,
|
|
131
|
+
ownerOnly: () => ownerOnly,
|
|
129
132
|
parseFileSizeLimit: () => parseFileSizeLimit,
|
|
130
133
|
policy: () => policy,
|
|
134
|
+
publicChannel: () => publicChannel,
|
|
131
135
|
raw: () => raw,
|
|
132
136
|
recordThrows: () => recordThrows,
|
|
133
137
|
reservedSecretKey: () => reservedSecretKey,
|
|
@@ -139,6 +143,7 @@ __export(src_exports, {
|
|
|
139
143
|
toSchemaJSON: () => toSchemaJSON,
|
|
140
144
|
uuid: () => uuid,
|
|
141
145
|
validateUploadAgainstStorage: () => validateUploadAgainstStorage,
|
|
146
|
+
vector: () => vector,
|
|
142
147
|
z: () => import_zod2.z
|
|
143
148
|
});
|
|
144
149
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -595,7 +600,8 @@ function makeTablesAccessor(ops) {
|
|
|
595
600
|
update: (id, data) => ops().update(name, id, data),
|
|
596
601
|
delete: (id) => ops().delete(name, id),
|
|
597
602
|
findById: (id) => ops().findById(name, id),
|
|
598
|
-
findMany: (query) => ops().findMany(name, query)
|
|
603
|
+
findMany: (query) => ops().findMany(name, query),
|
|
604
|
+
search: (params) => ops().search(name, params)
|
|
599
605
|
};
|
|
600
606
|
}
|
|
601
607
|
}
|
|
@@ -610,7 +616,8 @@ function makeTypedSurface(raw2) {
|
|
|
610
616
|
update: (table, id, data) => raw2.update(table, id, data),
|
|
611
617
|
delete: (table, id) => raw2.delete(table, id),
|
|
612
618
|
findById: (table, id) => raw2.findById(table, id),
|
|
613
|
-
findMany: (table, query) => raw2.findMany(table, query)
|
|
619
|
+
findMany: (table, query) => raw2.findMany(table, query),
|
|
620
|
+
search: (table, params) => raw2.search(table, params)
|
|
614
621
|
};
|
|
615
622
|
return Object.assign(ops, {
|
|
616
623
|
tables: makeTablesAccessor(() => raw2),
|
|
@@ -1553,7 +1560,88 @@ function mintToken(secret2) {
|
|
|
1553
1560
|
}
|
|
1554
1561
|
function buildRealtimeClient(cfg) {
|
|
1555
1562
|
const url = `${cfg.baseUrl}/realtime/api/broadcast`;
|
|
1563
|
+
const stateUrl = `${cfg.baseUrl}/realtime/api/state`;
|
|
1564
|
+
async function writeState(topic, key, value, del) {
|
|
1565
|
+
if (typeof topic !== "string" || topic.length === 0) {
|
|
1566
|
+
return {
|
|
1567
|
+
data: null,
|
|
1568
|
+
error: new PalbaseModuleError("invalid_argument", "topic must be a non-empty string", 400)
|
|
1569
|
+
};
|
|
1570
|
+
}
|
|
1571
|
+
if (typeof key !== "string" || key.length === 0) {
|
|
1572
|
+
return {
|
|
1573
|
+
data: null,
|
|
1574
|
+
error: new PalbaseModuleError("invalid_argument", "key must be a non-empty string", 400)
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
if (!cfg.apiJwtSecret) {
|
|
1578
|
+
return {
|
|
1579
|
+
data: null,
|
|
1580
|
+
error: new PalbaseModuleError(
|
|
1581
|
+
"realtime_unconfigured",
|
|
1582
|
+
"Realtime.state is unavailable: realtime is not provisioned for this Environment (PALBASE_REALTIME_API_JWT_SECRET unset).",
|
|
1583
|
+
503
|
|
1584
|
+
)
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
let token;
|
|
1588
|
+
try {
|
|
1589
|
+
token = mintToken(cfg.apiJwtSecret);
|
|
1590
|
+
} catch (err) {
|
|
1591
|
+
return {
|
|
1592
|
+
data: null,
|
|
1593
|
+
error: new PalbaseModuleError(
|
|
1594
|
+
"realtime_token_error",
|
|
1595
|
+
err instanceof Error ? err.message : "token mint failed",
|
|
1596
|
+
500
|
|
1597
|
+
)
|
|
1598
|
+
};
|
|
1599
|
+
}
|
|
1600
|
+
const op = del ? { topic, key, del: true } : { topic, key, value: value ?? {} };
|
|
1601
|
+
const doFetch = cfg.fetchImpl ?? globalThis.fetch;
|
|
1602
|
+
let response;
|
|
1603
|
+
try {
|
|
1604
|
+
response = await doFetch(stateUrl, {
|
|
1605
|
+
method: "POST",
|
|
1606
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` },
|
|
1607
|
+
body: JSON.stringify({ ops: [op] })
|
|
1608
|
+
});
|
|
1609
|
+
} catch (err) {
|
|
1610
|
+
return {
|
|
1611
|
+
data: null,
|
|
1612
|
+
error: new PalbaseModuleError(
|
|
1613
|
+
"network_error",
|
|
1614
|
+
err instanceof Error ? err.message : "state request failed",
|
|
1615
|
+
0
|
|
1616
|
+
)
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
if (response.status === 202 || response.status === 200) {
|
|
1620
|
+
return { data: void 0, error: null };
|
|
1621
|
+
}
|
|
1622
|
+
const detail = await response.text().catch(() => "");
|
|
1623
|
+
return {
|
|
1624
|
+
data: null,
|
|
1625
|
+
error: new PalbaseModuleError(
|
|
1626
|
+
"realtime_state_failed",
|
|
1627
|
+
`realtime state write returned ${response.status}${detail ? `: ${detail}` : ""}`,
|
|
1628
|
+
response.status
|
|
1629
|
+
)
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1556
1632
|
return {
|
|
1633
|
+
state: {
|
|
1634
|
+
/** Write one DURABLE entry on a channel's shared state.
|
|
1635
|
+
*
|
|
1636
|
+
* The difference from broadcast is WHO it reaches: a broadcast reaches
|
|
1637
|
+
* whoever is listening at that instant, while state is also handed to
|
|
1638
|
+
* whoever joins afterwards. "This value is now X" wants the second — a
|
|
1639
|
+
* client connecting a second later should not have to wait for the next
|
|
1640
|
+
* change to learn X. */
|
|
1641
|
+
set: (topic, key, value) => writeState(topic, key, value, false),
|
|
1642
|
+
/** Remove one entry. */
|
|
1643
|
+
clear: (topic, key) => writeState(topic, key, void 0, true)
|
|
1644
|
+
},
|
|
1557
1645
|
async broadcast(channel, event, payload) {
|
|
1558
1646
|
if (typeof channel !== "string" || channel.length === 0) {
|
|
1559
1647
|
return {
|
|
@@ -1861,6 +1949,26 @@ function defineSchema(input) {
|
|
|
1861
1949
|
if (table.raw !== void 0 && table.raw.length > 0) tableDef.raw = table.raw.slice();
|
|
1862
1950
|
if (table.checks !== void 0 && table.checks.length > 0) tableDef.checks = table.checks.slice();
|
|
1863
1951
|
if (table.indexes !== void 0 && table.indexes.length > 0) tableDef.indexes = table.indexes.slice();
|
|
1952
|
+
if (table.search !== void 0) {
|
|
1953
|
+
if (table.search.text === void 0 && table.search.vector === void 0) {
|
|
1954
|
+
throw new Error(
|
|
1955
|
+
`table ${String(name)}: search beyan\u0131 bo\u015F \u2014 en az bir kol (text ya da vector) verin, yoksa alan\u0131 hi\xE7 yazmay\u0131n`
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
if (table.search.text !== void 0 && table.search.text.length === 0) {
|
|
1959
|
+
throw new Error(`table ${String(name)}: search.text bo\u015F olamaz \u2014 FTS kolu istemiyorsan alan\u0131 hi\xE7 yazma`);
|
|
1960
|
+
}
|
|
1961
|
+
const legs = table.search.vector === void 0 ? [] : Array.isArray(table.search.vector) ? table.search.vector : [table.search.vector];
|
|
1962
|
+
for (const leg of legs) {
|
|
1963
|
+
if (leg.model !== void 0 && (leg.from === void 0 || leg.from.length === 0)) {
|
|
1964
|
+
throw new Error(`table ${String(name)}: search.vector.model beyan edildi ama 'from' yok \u2014 embed kayna\u011F\u0131 kolonlar zorunlu (C-2)`);
|
|
1965
|
+
}
|
|
1966
|
+
if (leg.model === void 0 && leg.from !== void 0) {
|
|
1967
|
+
throw new Error(`table ${String(name)}: search.vector.from model'siz anlams\u0131z \u2014 auto-embed i\xE7in model verin`);
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
tableDef.search = table.search;
|
|
1971
|
+
}
|
|
1864
1972
|
tables[name] = tableDef;
|
|
1865
1973
|
}
|
|
1866
1974
|
const extensions = [...new Set(input.extensions ?? [])];
|
|
@@ -1889,6 +1997,7 @@ function columnToJSON(column) {
|
|
|
1889
1997
|
if (def.enumName !== void 0) out.enumName = def.enumName;
|
|
1890
1998
|
if (def.enumValues !== void 0) out.enumValues = [...def.enumValues];
|
|
1891
1999
|
if (def.unique === true) out.unique = true;
|
|
2000
|
+
if (def.dimensions !== void 0) out.dimensions = def.dimensions;
|
|
1892
2001
|
return out;
|
|
1893
2002
|
}
|
|
1894
2003
|
function policyToJSON(policy2) {
|
|
@@ -1904,6 +2013,30 @@ function policyToJSON(policy2) {
|
|
|
1904
2013
|
permissive: policy2.permissive !== false
|
|
1905
2014
|
};
|
|
1906
2015
|
}
|
|
2016
|
+
function searchToJSON(search) {
|
|
2017
|
+
const out = {};
|
|
2018
|
+
if (search.text !== void 0 && search.text.length > 0) out.text = { columns: [...search.text] };
|
|
2019
|
+
const legs = search.vector === void 0 ? [] : Array.isArray(search.vector) ? search.vector : [search.vector];
|
|
2020
|
+
if (legs.length > 0) {
|
|
2021
|
+
out.vector = legs.map((leg) => {
|
|
2022
|
+
const v = { metric: leg.metric ?? "cosine" };
|
|
2023
|
+
if (leg.column !== void 0) v.column = leg.column;
|
|
2024
|
+
if (leg.staleness !== void 0) v.staleness = leg.staleness;
|
|
2025
|
+
if (leg.model !== void 0) {
|
|
2026
|
+
v.embed = {
|
|
2027
|
+
provider: leg.model.provider,
|
|
2028
|
+
model: leg.model.model,
|
|
2029
|
+
from: [...leg.from ?? []],
|
|
2030
|
+
...leg.model.apiKeyName !== void 0 ? { apiKeyName: leg.model.apiKeyName } : {},
|
|
2031
|
+
...leg.model.dimensions !== void 0 ? { dimensions: leg.model.dimensions } : {},
|
|
2032
|
+
...leg.model.baseURL !== void 0 ? { baseURL: leg.model.baseURL } : {}
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
return v;
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
return out;
|
|
2039
|
+
}
|
|
1907
2040
|
function tableToJSON(table) {
|
|
1908
2041
|
const columns = {};
|
|
1909
2042
|
for (const [name, column] of Object.entries(table.columns)) {
|
|
@@ -1939,6 +2072,10 @@ function tableToJSON(table) {
|
|
|
1939
2072
|
if (table.indexes !== void 0 && table.indexes.length > 0) {
|
|
1940
2073
|
out.indexes = table.indexes.map((i) => ({ name: i.name, columns: [...i.columns] }));
|
|
1941
2074
|
}
|
|
2075
|
+
if (table.search !== void 0) {
|
|
2076
|
+
const sj = searchToJSON(table.search);
|
|
2077
|
+
if (sj.text !== void 0 || sj.vector !== void 0) out.search = sj;
|
|
2078
|
+
}
|
|
1942
2079
|
return out;
|
|
1943
2080
|
}
|
|
1944
2081
|
function toSchemaJSON(schema) {
|
|
@@ -1950,6 +2087,63 @@ function toSchemaJSON(schema) {
|
|
|
1950
2087
|
return { tables, extensions: [...new Set(schema.extensions ?? [])] };
|
|
1951
2088
|
}
|
|
1952
2089
|
|
|
2090
|
+
// src/channels.ts
|
|
2091
|
+
var CHANNELS = /* @__PURE__ */ Symbol.for("palbase.backend.channels");
|
|
2092
|
+
function ownerOnly() {
|
|
2093
|
+
return { kind: "owner" };
|
|
2094
|
+
}
|
|
2095
|
+
function publicChannel(opts = {}) {
|
|
2096
|
+
return { kind: "public", publish: opts.publish ?? false, state: opts.state };
|
|
2097
|
+
}
|
|
2098
|
+
function paramCount(pattern) {
|
|
2099
|
+
return pattern.split(":").filter((s) => s.startsWith("{") && s.endsWith("}")).length;
|
|
2100
|
+
}
|
|
2101
|
+
function defineChannels(map) {
|
|
2102
|
+
const entries = [];
|
|
2103
|
+
for (const [pattern, entry] of Object.entries(map)) {
|
|
2104
|
+
if ("kind" in entry && entry.kind === "owner") {
|
|
2105
|
+
if (paramCount(pattern) !== 1) {
|
|
2106
|
+
throw new Error(
|
|
2107
|
+
`defineChannels: ownerOnly() pattern "${pattern}" must carry exactly one {param} (its value is compared to the token subject)`
|
|
2108
|
+
);
|
|
2109
|
+
}
|
|
2110
|
+
entries.push({ pattern, kind: "owner" });
|
|
2111
|
+
} else if ("kind" in entry && entry.kind === "public") {
|
|
2112
|
+
entries.push({ pattern, kind: "public", publish: entry.publish, state: entry.state });
|
|
2113
|
+
} else {
|
|
2114
|
+
const c = entry;
|
|
2115
|
+
entries.push({ pattern, kind: "custom", authorize: c.authorize, handler: c.handler });
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
const def = { entries };
|
|
2119
|
+
const carrier = globalThis;
|
|
2120
|
+
const existing = carrier[CHANNELS];
|
|
2121
|
+
if (existing && !sameDeclaration(existing, def)) {
|
|
2122
|
+
throw new Error(
|
|
2123
|
+
`defineChannels: channels were already declared (${existing.entries.length} pattern(s): ${existing.entries.map((e) => e.pattern).join(", ")}). A project declares its channels ONCE \u2014 a second call would overwrite the first, and channels nobody declared are refused.`
|
|
2124
|
+
);
|
|
2125
|
+
}
|
|
2126
|
+
carrier[CHANNELS] = def;
|
|
2127
|
+
return def;
|
|
2128
|
+
}
|
|
2129
|
+
function wireRow(e) {
|
|
2130
|
+
return JSON.stringify([
|
|
2131
|
+
e.pattern,
|
|
2132
|
+
e.kind,
|
|
2133
|
+
e.publish ?? false,
|
|
2134
|
+
e.state?.read ?? false,
|
|
2135
|
+
e.state?.write ?? false,
|
|
2136
|
+
// The handler is compared by SOURCE, like authorize: two evaluations of one
|
|
2137
|
+
// module give the same text, while different logic gives different text.
|
|
2138
|
+
e.handler ? e.handler.toString() : "",
|
|
2139
|
+
e.authorize ? e.authorize.toString() : ""
|
|
2140
|
+
]);
|
|
2141
|
+
}
|
|
2142
|
+
function sameDeclaration(a, b) {
|
|
2143
|
+
if (a.entries.length !== b.entries.length) return false;
|
|
2144
|
+
return a.entries.every((x, i) => wireRow(x) === wireRow(b.entries[i]));
|
|
2145
|
+
}
|
|
2146
|
+
|
|
1953
2147
|
// src/db/extensions.ts
|
|
1954
2148
|
var PALBASE_EXTENSIONS = [
|
|
1955
2149
|
// Search & text
|
|
@@ -1963,8 +2157,6 @@ var PALBASE_EXTENSIONS = [
|
|
|
1963
2157
|
"citext",
|
|
1964
2158
|
// case-insensitive text type
|
|
1965
2159
|
// Geospatial / location
|
|
1966
|
-
"postgis",
|
|
1967
|
-
// geospatial types + queries (maps, "near me")
|
|
1968
2160
|
"cube",
|
|
1969
2161
|
// multi-dimensional cubes (dependency of earthdistance)
|
|
1970
2162
|
"earthdistance",
|
|
@@ -1979,8 +2171,6 @@ var PALBASE_EXTENSIONS = [
|
|
|
1979
2171
|
// GiST operator classes for scalar types — needed for EXCLUDE
|
|
1980
2172
|
// constraints that mix "=" with a range/&& overlap (e.g. no-double-booking).
|
|
1981
2173
|
// Scheduling
|
|
1982
|
-
"pg_cron",
|
|
1983
|
-
// schedule jobs inside the database
|
|
1984
2174
|
// Crypto / ids (also installed by default; listable for explicitness)
|
|
1985
2175
|
"pgcrypto",
|
|
1986
2176
|
// cryptographic functions (hashing, encryption)
|
|
@@ -1995,6 +2185,11 @@ function isPalbaseExtension(name) {
|
|
|
1995
2185
|
}
|
|
1996
2186
|
|
|
1997
2187
|
// src/db/columns.ts
|
|
2188
|
+
function refuseOnVector(def, modifier) {
|
|
2189
|
+
if (def.type === "vector") {
|
|
2190
|
+
throw new Error(`vector column: .${modifier}() is not supported (FR-002 \u2014 allowed: nullable()/notNull())`);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
1998
2193
|
var ColumnBuilder = class _ColumnBuilder {
|
|
1999
2194
|
_def;
|
|
2000
2195
|
constructor(type, existingDef) {
|
|
@@ -2006,6 +2201,7 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2006
2201
|
}
|
|
2007
2202
|
/** Mark this column as the primary key. */
|
|
2008
2203
|
primaryKey() {
|
|
2204
|
+
refuseOnVector(this._def, "primaryKey");
|
|
2009
2205
|
this._def.primaryKey = true;
|
|
2010
2206
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2011
2207
|
}
|
|
@@ -2021,16 +2217,19 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2021
2217
|
}
|
|
2022
2218
|
/** Set a default value. */
|
|
2023
2219
|
default(value) {
|
|
2220
|
+
refuseOnVector(this._def, "default");
|
|
2024
2221
|
this._def.defaultValue = value;
|
|
2025
2222
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2026
2223
|
}
|
|
2027
2224
|
/** UUID: generate a random default (gen_random_uuid()). */
|
|
2028
2225
|
defaultRandom() {
|
|
2226
|
+
refuseOnVector(this._def, "defaultRandom");
|
|
2029
2227
|
this._def.defaultRandom = true;
|
|
2030
2228
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2031
2229
|
}
|
|
2032
2230
|
/** Timestamp: default to now(). */
|
|
2033
2231
|
defaultNow() {
|
|
2232
|
+
refuseOnVector(this._def, "defaultNow");
|
|
2034
2233
|
this._def.defaultNow = true;
|
|
2035
2234
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2036
2235
|
}
|
|
@@ -2051,6 +2250,7 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2051
2250
|
return this;
|
|
2052
2251
|
}
|
|
2053
2252
|
references(table, column) {
|
|
2253
|
+
refuseOnVector(this._def, "references");
|
|
2054
2254
|
this._def.references = { table, column };
|
|
2055
2255
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2056
2256
|
}
|
|
@@ -2075,6 +2275,7 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2075
2275
|
* as the real boundary; this signature is the compile-time DX mirror.
|
|
2076
2276
|
*/
|
|
2077
2277
|
referencesAuthUser(onDelete) {
|
|
2278
|
+
refuseOnVector(this._def, "referencesAuthUser");
|
|
2078
2279
|
this._def.references = { table: "auth.users", column: "id" };
|
|
2079
2280
|
this._def.onDeleteAction = onDelete;
|
|
2080
2281
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
@@ -2098,6 +2299,7 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2098
2299
|
* boundary; this signature is the compile-time DX mirror.
|
|
2099
2300
|
*/
|
|
2100
2301
|
referencesInstallation(onDelete) {
|
|
2302
|
+
refuseOnVector(this._def, "referencesInstallation");
|
|
2101
2303
|
this._def.references = { table: "auth.installations", column: "id" };
|
|
2102
2304
|
this._def.onDeleteAction = onDelete;
|
|
2103
2305
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
@@ -2109,6 +2311,7 @@ var ColumnBuilder = class _ColumnBuilder {
|
|
|
2109
2311
|
}
|
|
2110
2312
|
/** Add a single-column UNIQUE constraint. */
|
|
2111
2313
|
unique() {
|
|
2314
|
+
refuseOnVector(this._def, "unique");
|
|
2112
2315
|
this._def.unique = true;
|
|
2113
2316
|
return new _ColumnBuilder(this._def.type, this._def);
|
|
2114
2317
|
}
|
|
@@ -2143,12 +2346,33 @@ function enumType(name, values) {
|
|
|
2143
2346
|
builder._def.enumValues = [...values];
|
|
2144
2347
|
return builder;
|
|
2145
2348
|
}
|
|
2349
|
+
function vector(dimensions) {
|
|
2350
|
+
if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2e3) {
|
|
2351
|
+
throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);
|
|
2352
|
+
}
|
|
2353
|
+
const b = new ColumnBuilder("vector");
|
|
2354
|
+
b._def.dimensions = dimensions;
|
|
2355
|
+
return b;
|
|
2356
|
+
}
|
|
2146
2357
|
|
|
2147
2358
|
// src/db/raw.ts
|
|
2148
2359
|
function raw(name, up, opts) {
|
|
2149
2360
|
return { name, up, ...opts?.down != null ? { down: opts.down } : {} };
|
|
2150
2361
|
}
|
|
2151
2362
|
|
|
2363
|
+
// src/db/embedding.ts
|
|
2364
|
+
var openai = {
|
|
2365
|
+
embedding(model, opts) {
|
|
2366
|
+
return {
|
|
2367
|
+
provider: "openai",
|
|
2368
|
+
model,
|
|
2369
|
+
apiKeyName: opts?.apiKeyName ?? "OPENAI_API_KEY",
|
|
2370
|
+
...opts?.dimensions !== void 0 ? { dimensions: opts.dimensions } : {},
|
|
2371
|
+
...opts?.baseURL !== void 0 ? { baseURL: opts.baseURL } : {}
|
|
2372
|
+
};
|
|
2373
|
+
}
|
|
2374
|
+
};
|
|
2375
|
+
|
|
2152
2376
|
// src/db/typed-db.ts
|
|
2153
2377
|
function makeTypedTable(name, raw2) {
|
|
2154
2378
|
return {
|
|
@@ -2208,6 +2432,11 @@ function baseTsType(def) {
|
|
|
2208
2432
|
return "boolean";
|
|
2209
2433
|
case "jsonb":
|
|
2210
2434
|
return "unknown";
|
|
2435
|
+
// FR-008: the authoring type of a pgvector column. The default `unknown`
|
|
2436
|
+
// branch below STAYS — an unknown wire type is refused on the Go side
|
|
2437
|
+
// (FR-005), never papered over here.
|
|
2438
|
+
case "vector":
|
|
2439
|
+
return "number[]";
|
|
2211
2440
|
case "enum": {
|
|
2212
2441
|
const values = def.enumValues ?? [];
|
|
2213
2442
|
if (values.length === 0) return "string";
|
|
@@ -2289,6 +2518,10 @@ function tableBlock(table, children, indent) {
|
|
|
2289
2518
|
`${indent} };`,
|
|
2290
2519
|
`${indent} owner: ${owner === null ? "null" : JSON.stringify(owner)};`,
|
|
2291
2520
|
`${indent} children: {${childEntries === "" ? "" : ` ${childEntries} `}};`,
|
|
2521
|
+
// searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()
|
|
2522
|
+
// üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki
|
|
2523
|
+
// mevcut şemaların d.ts'i bayt-aynı kalsın.
|
|
2524
|
+
...cols.some(([, b]) => b._def.type === "vector") || table.search !== void 0 ? [`${indent} searchable: true;`] : [],
|
|
2292
2525
|
`${indent}};`
|
|
2293
2526
|
].join("\n");
|
|
2294
2527
|
}
|
|
@@ -3741,6 +3974,7 @@ var import_zod2 = require("zod");
|
|
|
3741
3974
|
buildModuleClients,
|
|
3742
3975
|
buildProvider,
|
|
3743
3976
|
dec,
|
|
3977
|
+
defineChannels,
|
|
3744
3978
|
defineEgress,
|
|
3745
3979
|
defineError,
|
|
3746
3980
|
defineFlags,
|
|
@@ -3770,8 +4004,11 @@ var import_zod2 = require("zod");
|
|
|
3770
4004
|
makeTypedDB,
|
|
3771
4005
|
now,
|
|
3772
4006
|
numeric,
|
|
4007
|
+
openai,
|
|
4008
|
+
ownerOnly,
|
|
3773
4009
|
parseFileSizeLimit,
|
|
3774
4010
|
policy,
|
|
4011
|
+
publicChannel,
|
|
3775
4012
|
raw,
|
|
3776
4013
|
recordThrows,
|
|
3777
4014
|
reservedSecretKey,
|
|
@@ -3783,6 +4020,7 @@ var import_zod2 = require("zod");
|
|
|
3783
4020
|
toSchemaJSON,
|
|
3784
4021
|
uuid,
|
|
3785
4022
|
validateUploadAgainstStorage,
|
|
4023
|
+
vector,
|
|
3786
4024
|
z
|
|
3787
4025
|
});
|
|
3788
4026
|
//# sourceMappingURL=index.cjs.map
|