@onyx.dev/onyx-database 1.0.2 → 1.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/README.md +137 -2
- package/dist/aggregates-DodZNu9-.d.cts +1453 -0
- package/dist/aggregates-DodZNu9-.d.ts +1453 -0
- package/dist/edge.cjs +1976 -0
- package/dist/edge.cjs.map +1 -0
- package/dist/edge.d.cts +9 -0
- package/dist/edge.d.ts +9 -0
- package/dist/edge.js +1932 -0
- package/dist/edge.js.map +1 -0
- package/dist/gen/cli/generate.cjs +94 -41
- package/dist/gen/cli/generate.cjs.map +1 -1
- package/dist/index.cjs +100 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1407
- package/dist/index.d.ts +3 -1407
- package/dist/index.js +100 -41
- package/dist/index.js.map +1 -1
- package/dist/schema/cli/schema.cjs +94 -40
- package/dist/schema/cli/schema.cjs.map +1 -1
- package/package.json +22 -5
package/dist/index.cjs
CHANGED
|
@@ -211,6 +211,10 @@ async function resolveConfig(input) {
|
|
|
211
211
|
const fetchImpl = merged.fetch ?? (typeof gfetch === "function" ? (u, i) => gfetch(u, i) : async () => {
|
|
212
212
|
throw new OnyxConfigError("No fetch available; provide OnyxConfig.fetch");
|
|
213
213
|
});
|
|
214
|
+
const retryConfig = input?.retry ?? env.retry ?? cfgPath.retry ?? project.retry ?? home.retry ?? {};
|
|
215
|
+
const retryEnabled = retryConfig.enabled ?? true;
|
|
216
|
+
const maxRetries = retryConfig.maxRetries ?? 3;
|
|
217
|
+
const retryInitialDelayMs = retryConfig.initialDelayMs ?? 300;
|
|
214
218
|
const missing = [];
|
|
215
219
|
if (!databaseId) missing.push("databaseId");
|
|
216
220
|
if (!apiKey) missing.push("apiKey");
|
|
@@ -233,7 +237,16 @@ async function resolveConfig(input) {
|
|
|
233
237
|
`Missing required config: ${missing.join(", ")}. Sources: ${sources.join(", ")}`
|
|
234
238
|
);
|
|
235
239
|
}
|
|
236
|
-
const resolved = {
|
|
240
|
+
const resolved = {
|
|
241
|
+
baseUrl,
|
|
242
|
+
databaseId,
|
|
243
|
+
apiKey,
|
|
244
|
+
apiSecret,
|
|
245
|
+
fetch: fetchImpl,
|
|
246
|
+
retryEnabled,
|
|
247
|
+
maxRetries,
|
|
248
|
+
retryInitialDelayMs
|
|
249
|
+
};
|
|
237
250
|
const source = {
|
|
238
251
|
databaseId: input?.databaseId ? "explicit config" : env.databaseId ? "env" : cfgPath.databaseId ? "env ONYX_CONFIG_PATH" : project.databaseId ? "project file" : home.databaseId ? "home profile" : "unknown",
|
|
239
252
|
apiKey: input?.apiKey ? "explicit config" : env.apiKey ? "env" : cfgPath.apiKey ? "env ONYX_CONFIG_PATH" : project.apiKey ? "project file" : home.apiKey ? "home profile" : "unknown",
|
|
@@ -290,7 +303,7 @@ function parseJsonAllowNaN(txt) {
|
|
|
290
303
|
return JSON.parse(fixed);
|
|
291
304
|
}
|
|
292
305
|
}
|
|
293
|
-
var HttpClient = class {
|
|
306
|
+
var HttpClient = class _HttpClient {
|
|
294
307
|
baseUrl;
|
|
295
308
|
apiKey;
|
|
296
309
|
apiSecret;
|
|
@@ -298,6 +311,25 @@ var HttpClient = class {
|
|
|
298
311
|
defaults;
|
|
299
312
|
requestLoggingEnabled;
|
|
300
313
|
responseLoggingEnabled;
|
|
314
|
+
retryEnabled;
|
|
315
|
+
maxRetries;
|
|
316
|
+
retryInitialDelayMs;
|
|
317
|
+
shouldRetry;
|
|
318
|
+
static parseRetryAfter(header) {
|
|
319
|
+
if (!header) return null;
|
|
320
|
+
const trimmed = header.trim();
|
|
321
|
+
if (trimmed === "") return null;
|
|
322
|
+
const seconds = Number(trimmed);
|
|
323
|
+
if (Number.isFinite(seconds)) {
|
|
324
|
+
return Math.max(0, seconds * 1e3);
|
|
325
|
+
}
|
|
326
|
+
const dateMs = Date.parse(trimmed);
|
|
327
|
+
if (!Number.isNaN(dateMs)) {
|
|
328
|
+
const now = Date.now();
|
|
329
|
+
return Math.max(0, dateMs - now);
|
|
330
|
+
}
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
301
333
|
constructor(opts) {
|
|
302
334
|
if (!opts.baseUrl || opts.baseUrl.trim() === "") {
|
|
303
335
|
throw new OnyxConfigError("baseUrl is required");
|
|
@@ -322,6 +354,10 @@ var HttpClient = class {
|
|
|
322
354
|
const envDebug = globalThis.process?.env?.ONYX_DEBUG === "true";
|
|
323
355
|
this.requestLoggingEnabled = !!opts.requestLoggingEnabled || envDebug;
|
|
324
356
|
this.responseLoggingEnabled = !!opts.responseLoggingEnabled || envDebug;
|
|
357
|
+
this.retryEnabled = opts.retryEnabled ?? true;
|
|
358
|
+
this.maxRetries = Math.max(0, opts.maxRetries ?? 2);
|
|
359
|
+
this.retryInitialDelayMs = Math.max(0, opts.retryInitialDelayMs ?? 100);
|
|
360
|
+
this.shouldRetry = (method, path) => method === "GET" || path.startsWith("/query/");
|
|
325
361
|
}
|
|
326
362
|
headers(extra) {
|
|
327
363
|
const extras = { ...extra ?? {} };
|
|
@@ -362,9 +398,8 @@ var HttpClient = class {
|
|
|
362
398
|
headers,
|
|
363
399
|
body: payload
|
|
364
400
|
};
|
|
365
|
-
const
|
|
366
|
-
const
|
|
367
|
-
const maxAttempts = canRetry ? 3 : 1;
|
|
401
|
+
const canRetry = this.retryEnabled && this.shouldRetry(method, path);
|
|
402
|
+
const maxAttempts = canRetry ? this.maxRetries + 1 : 1;
|
|
368
403
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
369
404
|
try {
|
|
370
405
|
const res = await this.fetchImpl(url, init);
|
|
@@ -382,7 +417,10 @@ var HttpClient = class {
|
|
|
382
417
|
if (!res.ok) {
|
|
383
418
|
const msg = typeof data === "object" && data !== null && "error" in data && typeof data.error?.message === "string" ? String(data.error.message) : `${res.status} ${res.statusText}`;
|
|
384
419
|
if (canRetry && res.status >= 500 && attempt + 1 < maxAttempts) {
|
|
385
|
-
|
|
420
|
+
const serverRetry = _HttpClient.parseRetryAfter(res.headers.get("retry-after"));
|
|
421
|
+
const backoff = this.retryInitialDelayMs * 2 ** attempt;
|
|
422
|
+
const delay = serverRetry ?? backoff;
|
|
423
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
386
424
|
continue;
|
|
387
425
|
}
|
|
388
426
|
throw new OnyxHttpError(msg, res.status, res.statusText, data, raw);
|
|
@@ -391,7 +429,8 @@ var HttpClient = class {
|
|
|
391
429
|
} catch (err) {
|
|
392
430
|
const retryable = canRetry && (!(err instanceof OnyxHttpError) || err.status >= 500);
|
|
393
431
|
if (attempt + 1 < maxAttempts && retryable) {
|
|
394
|
-
|
|
432
|
+
const delay = this.retryInitialDelayMs * 2 ** attempt;
|
|
433
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
395
434
|
continue;
|
|
396
435
|
}
|
|
397
436
|
throw err;
|
|
@@ -952,14 +991,6 @@ var CascadeRelationshipBuilder = class {
|
|
|
952
991
|
}
|
|
953
992
|
};
|
|
954
993
|
|
|
955
|
-
// src/errors/onyx-error.ts
|
|
956
|
-
var OnyxError = class extends Error {
|
|
957
|
-
name = "OnyxError";
|
|
958
|
-
constructor(message) {
|
|
959
|
-
super(message);
|
|
960
|
-
}
|
|
961
|
-
};
|
|
962
|
-
|
|
963
994
|
// src/helpers/schema-diff.ts
|
|
964
995
|
function mapByName(items) {
|
|
965
996
|
const map = /* @__PURE__ */ new Map();
|
|
@@ -1148,23 +1179,8 @@ function computeSchemaDiff(apiSchema, localSchema) {
|
|
|
1148
1179
|
return { newTables, removedTables, changedTables };
|
|
1149
1180
|
}
|
|
1150
1181
|
|
|
1151
|
-
// src/impl/onyx.ts
|
|
1182
|
+
// src/impl/onyx-core.ts
|
|
1152
1183
|
var DEFAULT_CACHE_TTL = 5 * 60 * 1e3;
|
|
1153
|
-
var cachedCfg = null;
|
|
1154
|
-
function resolveConfigWithCache(config) {
|
|
1155
|
-
const ttl = config?.ttl ?? DEFAULT_CACHE_TTL;
|
|
1156
|
-
const now = Date.now();
|
|
1157
|
-
if (cachedCfg && cachedCfg.expires > now) {
|
|
1158
|
-
return cachedCfg.promise;
|
|
1159
|
-
}
|
|
1160
|
-
const { ttl: _ttl, requestLoggingEnabled: _reqLog, responseLoggingEnabled: _resLog, ...rest } = config ?? {};
|
|
1161
|
-
const promise = resolveConfig(rest);
|
|
1162
|
-
cachedCfg = { promise, expires: now + ttl };
|
|
1163
|
-
return promise;
|
|
1164
|
-
}
|
|
1165
|
-
function clearCacheConfig() {
|
|
1166
|
-
cachedCfg = null;
|
|
1167
|
-
}
|
|
1168
1184
|
function toSingleCondition(criteria) {
|
|
1169
1185
|
return { conditionType: "SingleCondition", criteria };
|
|
1170
1186
|
}
|
|
@@ -1254,7 +1270,7 @@ var OnyxDatabaseImpl = class {
|
|
|
1254
1270
|
requestLoggingEnabled;
|
|
1255
1271
|
responseLoggingEnabled;
|
|
1256
1272
|
defaultPartition;
|
|
1257
|
-
constructor(config) {
|
|
1273
|
+
constructor(config, resolveConfigWithCache) {
|
|
1258
1274
|
this.requestLoggingEnabled = !!config?.requestLoggingEnabled;
|
|
1259
1275
|
this.responseLoggingEnabled = !!config?.responseLoggingEnabled;
|
|
1260
1276
|
this.defaultPartition = config?.partition;
|
|
@@ -1271,7 +1287,10 @@ var OnyxDatabaseImpl = class {
|
|
|
1271
1287
|
apiSecret: this.resolved.apiSecret,
|
|
1272
1288
|
fetchImpl: this.resolved.fetch,
|
|
1273
1289
|
requestLoggingEnabled: this.requestLoggingEnabled,
|
|
1274
|
-
responseLoggingEnabled: this.responseLoggingEnabled
|
|
1290
|
+
responseLoggingEnabled: this.responseLoggingEnabled,
|
|
1291
|
+
retryEnabled: this.resolved.retryEnabled,
|
|
1292
|
+
maxRetries: this.resolved.maxRetries,
|
|
1293
|
+
retryInitialDelayMs: this.resolved.retryInitialDelayMs
|
|
1275
1294
|
});
|
|
1276
1295
|
}
|
|
1277
1296
|
return {
|
|
@@ -1306,6 +1325,14 @@ var OnyxDatabaseImpl = class {
|
|
|
1306
1325
|
qb.select(...fields);
|
|
1307
1326
|
return qb;
|
|
1308
1327
|
}
|
|
1328
|
+
search(queryText, minScore) {
|
|
1329
|
+
const qb = new QueryBuilderImpl(
|
|
1330
|
+
this,
|
|
1331
|
+
"ALL",
|
|
1332
|
+
this.defaultPartition
|
|
1333
|
+
);
|
|
1334
|
+
return qb.search(queryText, minScore);
|
|
1335
|
+
}
|
|
1309
1336
|
cascade(...relationships) {
|
|
1310
1337
|
const cb = new CascadeBuilderImpl(this);
|
|
1311
1338
|
return cb.cascade(...relationships);
|
|
@@ -1592,6 +1619,7 @@ var QueryBuilderImpl = class {
|
|
|
1592
1619
|
toSelectQuery() {
|
|
1593
1620
|
return {
|
|
1594
1621
|
type: "SelectQuery",
|
|
1622
|
+
table: this.table,
|
|
1595
1623
|
fields: this.fields,
|
|
1596
1624
|
conditions: this.serializableConditions(),
|
|
1597
1625
|
sort: this.sort,
|
|
@@ -1631,6 +1659,13 @@ var QueryBuilderImpl = class {
|
|
|
1631
1659
|
this.resolvers = flat.length > 0 ? flat : null;
|
|
1632
1660
|
return this;
|
|
1633
1661
|
}
|
|
1662
|
+
search(queryText, minScore) {
|
|
1663
|
+
return this.and({
|
|
1664
|
+
field: "__full_text__",
|
|
1665
|
+
operator: "MATCHES",
|
|
1666
|
+
value: { queryText, minScore: minScore ?? null }
|
|
1667
|
+
});
|
|
1668
|
+
}
|
|
1634
1669
|
where(condition) {
|
|
1635
1670
|
const c2 = toCondition(condition);
|
|
1636
1671
|
if (!this.conditions) {
|
|
@@ -1736,7 +1771,6 @@ var QueryBuilderImpl = class {
|
|
|
1736
1771
|
}
|
|
1737
1772
|
async firstOrNull() {
|
|
1738
1773
|
if (this.mode !== "select") throw new Error("Cannot call firstOrNull() in update mode.");
|
|
1739
|
-
if (!this.conditions) throw new OnyxError("firstOrNull() requires a where() clause.");
|
|
1740
1774
|
this.limitValue = 1;
|
|
1741
1775
|
const pg = await this.page();
|
|
1742
1776
|
return Array.isArray(pg.records) && pg.records.length > 0 ? pg.records[0] : null;
|
|
@@ -1828,12 +1862,32 @@ var CascadeBuilderImpl = class {
|
|
|
1828
1862
|
return this.db.delete(table, primaryKey, opts);
|
|
1829
1863
|
}
|
|
1830
1864
|
};
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1865
|
+
function createOnyxFacade(resolveConfig2) {
|
|
1866
|
+
let cachedCfg = null;
|
|
1867
|
+
function resolveConfigWithCache(config) {
|
|
1868
|
+
const ttl = config?.ttl ?? DEFAULT_CACHE_TTL;
|
|
1869
|
+
const now = Date.now();
|
|
1870
|
+
if (cachedCfg && cachedCfg.expires > now) {
|
|
1871
|
+
return cachedCfg.promise;
|
|
1872
|
+
}
|
|
1873
|
+
const { ttl: _ttl, requestLoggingEnabled: _reqLog, responseLoggingEnabled: _resLog, ...rest } = config ?? {};
|
|
1874
|
+
const promise = resolveConfig2(rest);
|
|
1875
|
+
cachedCfg = { promise, expires: now + ttl };
|
|
1876
|
+
return promise;
|
|
1877
|
+
}
|
|
1878
|
+
function clearCacheConfig() {
|
|
1879
|
+
cachedCfg = null;
|
|
1880
|
+
}
|
|
1881
|
+
return {
|
|
1882
|
+
init(config) {
|
|
1883
|
+
return new OnyxDatabaseImpl(config, resolveConfigWithCache);
|
|
1884
|
+
},
|
|
1885
|
+
clearCacheConfig
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
// src/impl/onyx.ts
|
|
1890
|
+
var onyx = createOnyxFacade((config) => resolveConfig(config));
|
|
1837
1891
|
|
|
1838
1892
|
// src/helpers/sort.ts
|
|
1839
1893
|
var asc = (field) => ({ field, order: "ASC" });
|
|
@@ -1963,6 +2017,10 @@ var ConditionBuilderImpl = class {
|
|
|
1963
2017
|
|
|
1964
2018
|
// src/helpers/conditions.ts
|
|
1965
2019
|
var c = (field, operator, value) => new ConditionBuilderImpl({ field, operator, value });
|
|
2020
|
+
var fullText = (queryText, minScore) => ({
|
|
2021
|
+
queryText,
|
|
2022
|
+
minScore: minScore ?? null
|
|
2023
|
+
});
|
|
1966
2024
|
var eq = (field, value) => c(field, "EQUAL", value);
|
|
1967
2025
|
var neq = (field, value) => c(field, "NOT_EQUAL", value);
|
|
1968
2026
|
function inOp(field, values) {
|
|
@@ -1985,6 +2043,7 @@ var gte = (field, value) => c(field, "GREATER_THAN_EQUAL", value);
|
|
|
1985
2043
|
var lt = (field, value) => c(field, "LESS_THAN", value);
|
|
1986
2044
|
var lte = (field, value) => c(field, "LESS_THAN_EQUAL", value);
|
|
1987
2045
|
var matches = (field, regex) => c(field, "MATCHES", regex);
|
|
2046
|
+
var search = (queryText, minScore) => c("__full_text__", "MATCHES", fullText(queryText, minScore));
|
|
1988
2047
|
var notMatches = (field, regex) => c(field, "NOT_MATCHES", regex);
|
|
1989
2048
|
var like = (field, pattern) => c(field, "LIKE", pattern);
|
|
1990
2049
|
var notLike = (field, pattern) => c(field, "NOT_LIKE", pattern);
|
|
@@ -2051,6 +2110,7 @@ exports.percentile = percentile;
|
|
|
2051
2110
|
exports.replace = replace;
|
|
2052
2111
|
exports.sdkName = sdkName;
|
|
2053
2112
|
exports.sdkVersion = sdkVersion;
|
|
2113
|
+
exports.search = search;
|
|
2054
2114
|
exports.startsWith = startsWith;
|
|
2055
2115
|
exports.std = std;
|
|
2056
2116
|
exports.substring = substring;
|