@xylex-group/athena 2.3.0 → 2.4.1
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 +195 -106
- package/dist/browser.cjs +870 -154
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +7 -7
- package/dist/browser.d.ts +7 -7
- package/dist/browser.js +869 -155
- package/dist/browser.js.map +1 -1
- package/dist/cli/index.cjs +905 -144
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +3 -3
- package/dist/cli/index.d.ts +3 -3
- package/dist/cli/index.js +905 -144
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +870 -154
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +869 -155
- package/dist/index.js.map +1 -1
- package/dist/{model-form-hoE2jHIi.d.cts → model-form-4LPnOPAF.d.cts} +9 -5
- package/dist/{model-form-BpDXlbxb.d.ts → model-form-CO4-LmNC.d.ts} +9 -5
- package/dist/{pipeline-BNIw8pDQ.d.ts → pipeline-CR4V15jF.d.ts} +1 -1
- package/dist/{pipeline-DNIpEsN8.d.cts → pipeline-DZeExYMA.d.cts} +1 -1
- package/dist/{react-email-qPA1wjFV.d.ts → react-email-6mOyxBo4.d.cts} +60 -13
- package/dist/{react-email-BvyCZnfW.d.cts → react-email-Buhcpglm.d.ts} +60 -13
- package/dist/react.cjs +333 -16
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +4 -4
- package/dist/react.d.ts +4 -4
- package/dist/react.js +333 -16
- package/dist/react.js.map +1 -1
- package/dist/{types-A5e97acl.d.cts → types-09Q4D86N.d.cts} +23 -2
- package/dist/{types-A5e97acl.d.ts → types-09Q4D86N.d.ts} +23 -2
- package/dist/{types-bDlr4u7p.d.cts → types-D1JvL21V.d.cts} +1 -1
- package/dist/{types-BnD22-vb.d.ts → types-DU3gNdFv.d.ts} +1 -1
- package/dist/utils.cjs +131 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +42 -1
- package/dist/utils.d.ts +42 -1
- package/dist/utils.js +117 -1
- package/dist/utils.js.map +1 -1
- package/package.json +40 -40
|
@@ -44,9 +44,12 @@ interface AthenaSortBy {
|
|
|
44
44
|
direction: AthenaSortDirection;
|
|
45
45
|
}
|
|
46
46
|
interface AthenaFetchPayload {
|
|
47
|
+
select?: string | AthenaJsonObject;
|
|
47
48
|
view_name?: string;
|
|
48
49
|
table_name?: string;
|
|
49
50
|
columns?: string[] | string;
|
|
51
|
+
where?: AthenaJsonObject;
|
|
52
|
+
orderBy?: AthenaJsonObject | AthenaJsonArray;
|
|
50
53
|
conditions?: AthenaGatewayCondition[];
|
|
51
54
|
limit?: number;
|
|
52
55
|
offset?: number;
|
|
@@ -54,6 +57,8 @@ interface AthenaFetchPayload {
|
|
|
54
57
|
page_size?: number;
|
|
55
58
|
total_pages?: number;
|
|
56
59
|
strip_nulls?: boolean;
|
|
60
|
+
count?: AthenaCountOption;
|
|
61
|
+
head?: boolean;
|
|
57
62
|
group_by?: string;
|
|
58
63
|
time_granularity?: 'day' | 'hour' | 'minute';
|
|
59
64
|
aggregation_column?: string;
|
|
@@ -165,7 +170,7 @@ interface AthenaGatewayResponse<T = unknown> {
|
|
|
165
170
|
errorDetails?: AthenaGatewayErrorDetails | null;
|
|
166
171
|
raw: unknown;
|
|
167
172
|
}
|
|
168
|
-
type AthenaGatewayErrorCode = 'NETWORK_ERROR' | 'HTTP_ERROR' | 'INVALID_JSON' | 'UNKNOWN_ERROR';
|
|
173
|
+
type AthenaGatewayErrorCode = 'NETWORK_ERROR' | 'INVALID_URL' | 'HTTP_ERROR' | 'INVALID_JSON' | 'UNKNOWN_ERROR';
|
|
169
174
|
interface AthenaGatewayErrorDetails {
|
|
170
175
|
code: AthenaGatewayErrorCode;
|
|
171
176
|
message: string;
|
|
@@ -176,6 +181,22 @@ interface AthenaGatewayErrorDetails {
|
|
|
176
181
|
hint?: string;
|
|
177
182
|
cause?: string;
|
|
178
183
|
}
|
|
184
|
+
interface AthenaGatewayConnectionOptions {
|
|
185
|
+
path?: `/${string}`;
|
|
186
|
+
headers?: Record<string, string>;
|
|
187
|
+
signal?: AbortSignal;
|
|
188
|
+
}
|
|
189
|
+
interface AthenaGatewayConnectionResult {
|
|
190
|
+
ok: boolean;
|
|
191
|
+
reachable: boolean;
|
|
192
|
+
status: number;
|
|
193
|
+
statusText?: string | null;
|
|
194
|
+
baseUrl: string;
|
|
195
|
+
url: string;
|
|
196
|
+
error?: string;
|
|
197
|
+
errorDetails?: AthenaGatewayErrorDetails | null;
|
|
198
|
+
raw: unknown;
|
|
199
|
+
}
|
|
179
200
|
interface AthenaGatewayResponseLog extends AthenaGatewayResponse {
|
|
180
201
|
timestamp: string;
|
|
181
202
|
}
|
|
@@ -378,4 +399,4 @@ interface SchemaIntrospectionProvider {
|
|
|
378
399
|
inspect(options?: IntrospectionInspectOptions): Promise<IntrospectionSnapshot>;
|
|
379
400
|
}
|
|
380
401
|
|
|
381
|
-
export { type AthenaConditionCastType as A, Backend as B, type
|
|
402
|
+
export { type AthenaConditionCastType as A, Backend as B, type ModelRelationMetadata as C, type DatabaseDef as D, type RowOf as E, type SchemaDef as F, type TenantContextValue as G, type TenantKeyMap as H, type IntrospectionSnapshot as I, type AthenaConditionValue as J, type AthenaConditionArrayValue as K, type AnyModelDef as L, type ModelAt as M, type AthenaConditionOperator as N, type AthenaGatewayHookConfig as O, type AthenaGatewayHookResult as P, type AthenaDeletePayload as Q, type RegistryDef as R, type SchemaIntrospectionProvider as S, type TenantContext as T, type UpdateOf as U, type AthenaFetchPayload as V, type AthenaGatewayResponse as W, type AthenaInsertPayload as X, type AthenaUpdatePayload as Y, type AthenaGatewayEndpointPath as Z, type AthenaGatewayMethod as _, type AthenaGatewayCallOptions as a, type AthenaGatewayConnectionOptions as b, type AthenaGatewayConnectionResult as c, type AthenaGatewayErrorCode as d, type AthenaGatewayErrorDetails as e, type AthenaJsonArray as f, type AthenaJsonObject as g, type AthenaJsonPrimitive as h, type AthenaJsonValue as i, type AthenaRpcCallOptions as j, type AthenaRpcFilter as k, type AthenaRpcFilterOperator as l, type AthenaRpcOrder as m, type AthenaRpcPayload as n, type BackendConfig as o, type BackendType as p, type InsertOf as q, type IntrospectionColumn as r, type IntrospectionInspectOptions as s, type IntrospectionRelation as t, type IntrospectionSchema as u, type IntrospectionTable as v, type IntrospectionTypeKind as w, type ModelDef as x, type ModelMetadata as y, type ModelRelationKind as z };
|
|
@@ -44,9 +44,12 @@ interface AthenaSortBy {
|
|
|
44
44
|
direction: AthenaSortDirection;
|
|
45
45
|
}
|
|
46
46
|
interface AthenaFetchPayload {
|
|
47
|
+
select?: string | AthenaJsonObject;
|
|
47
48
|
view_name?: string;
|
|
48
49
|
table_name?: string;
|
|
49
50
|
columns?: string[] | string;
|
|
51
|
+
where?: AthenaJsonObject;
|
|
52
|
+
orderBy?: AthenaJsonObject | AthenaJsonArray;
|
|
50
53
|
conditions?: AthenaGatewayCondition[];
|
|
51
54
|
limit?: number;
|
|
52
55
|
offset?: number;
|
|
@@ -54,6 +57,8 @@ interface AthenaFetchPayload {
|
|
|
54
57
|
page_size?: number;
|
|
55
58
|
total_pages?: number;
|
|
56
59
|
strip_nulls?: boolean;
|
|
60
|
+
count?: AthenaCountOption;
|
|
61
|
+
head?: boolean;
|
|
57
62
|
group_by?: string;
|
|
58
63
|
time_granularity?: 'day' | 'hour' | 'minute';
|
|
59
64
|
aggregation_column?: string;
|
|
@@ -165,7 +170,7 @@ interface AthenaGatewayResponse<T = unknown> {
|
|
|
165
170
|
errorDetails?: AthenaGatewayErrorDetails | null;
|
|
166
171
|
raw: unknown;
|
|
167
172
|
}
|
|
168
|
-
type AthenaGatewayErrorCode = 'NETWORK_ERROR' | 'HTTP_ERROR' | 'INVALID_JSON' | 'UNKNOWN_ERROR';
|
|
173
|
+
type AthenaGatewayErrorCode = 'NETWORK_ERROR' | 'INVALID_URL' | 'HTTP_ERROR' | 'INVALID_JSON' | 'UNKNOWN_ERROR';
|
|
169
174
|
interface AthenaGatewayErrorDetails {
|
|
170
175
|
code: AthenaGatewayErrorCode;
|
|
171
176
|
message: string;
|
|
@@ -176,6 +181,22 @@ interface AthenaGatewayErrorDetails {
|
|
|
176
181
|
hint?: string;
|
|
177
182
|
cause?: string;
|
|
178
183
|
}
|
|
184
|
+
interface AthenaGatewayConnectionOptions {
|
|
185
|
+
path?: `/${string}`;
|
|
186
|
+
headers?: Record<string, string>;
|
|
187
|
+
signal?: AbortSignal;
|
|
188
|
+
}
|
|
189
|
+
interface AthenaGatewayConnectionResult {
|
|
190
|
+
ok: boolean;
|
|
191
|
+
reachable: boolean;
|
|
192
|
+
status: number;
|
|
193
|
+
statusText?: string | null;
|
|
194
|
+
baseUrl: string;
|
|
195
|
+
url: string;
|
|
196
|
+
error?: string;
|
|
197
|
+
errorDetails?: AthenaGatewayErrorDetails | null;
|
|
198
|
+
raw: unknown;
|
|
199
|
+
}
|
|
179
200
|
interface AthenaGatewayResponseLog extends AthenaGatewayResponse {
|
|
180
201
|
timestamp: string;
|
|
181
202
|
}
|
|
@@ -378,4 +399,4 @@ interface SchemaIntrospectionProvider {
|
|
|
378
399
|
inspect(options?: IntrospectionInspectOptions): Promise<IntrospectionSnapshot>;
|
|
379
400
|
}
|
|
380
401
|
|
|
381
|
-
export { type AthenaConditionCastType as A, Backend as B, type
|
|
402
|
+
export { type AthenaConditionCastType as A, Backend as B, type ModelRelationMetadata as C, type DatabaseDef as D, type RowOf as E, type SchemaDef as F, type TenantContextValue as G, type TenantKeyMap as H, type IntrospectionSnapshot as I, type AthenaConditionValue as J, type AthenaConditionArrayValue as K, type AnyModelDef as L, type ModelAt as M, type AthenaConditionOperator as N, type AthenaGatewayHookConfig as O, type AthenaGatewayHookResult as P, type AthenaDeletePayload as Q, type RegistryDef as R, type SchemaIntrospectionProvider as S, type TenantContext as T, type UpdateOf as U, type AthenaFetchPayload as V, type AthenaGatewayResponse as W, type AthenaInsertPayload as X, type AthenaUpdatePayload as Y, type AthenaGatewayEndpointPath as Z, type AthenaGatewayMethod as _, type AthenaGatewayCallOptions as a, type AthenaGatewayConnectionOptions as b, type AthenaGatewayConnectionResult as c, type AthenaGatewayErrorCode as d, type AthenaGatewayErrorDetails as e, type AthenaJsonArray as f, type AthenaJsonObject as g, type AthenaJsonPrimitive as h, type AthenaJsonValue as i, type AthenaRpcCallOptions as j, type AthenaRpcFilter as k, type AthenaRpcFilterOperator as l, type AthenaRpcOrder as m, type AthenaRpcPayload as n, type BackendConfig as o, type BackendType as p, type InsertOf as q, type IntrospectionColumn as r, type IntrospectionInspectOptions as s, type IntrospectionRelation as t, type IntrospectionSchema as u, type IntrospectionTable as v, type IntrospectionTypeKind as w, type ModelDef as x, type ModelMetadata as y, type ModelRelationKind as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { p as BackendType, I as IntrospectionSnapshot, S as SchemaIntrospectionProvider } from './types-09Q4D86N.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Supported case transformations for generated symbols and path token variants.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { p as BackendType, I as IntrospectionSnapshot, S as SchemaIntrospectionProvider } from './types-09Q4D86N.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Supported case transformations for generated symbols and path token variants.
|
package/dist/utils.cjs
CHANGED
|
@@ -10,6 +10,79 @@ function trimTrailingSlashes(value) {
|
|
|
10
10
|
return value.replace(/\/+$/, "");
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// src/utils/coercions.ts
|
|
14
|
+
var BOOLEAN_TRUE_TOKENS = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
|
|
15
|
+
var BOOLEAN_FALSE_TOKENS = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
|
|
16
|
+
function parseBooleanToken(value) {
|
|
17
|
+
const normalized = value.trim().toLowerCase();
|
|
18
|
+
if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true;
|
|
19
|
+
if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false;
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
function asString(value) {
|
|
23
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
24
|
+
if (typeof value === "bigint") return value.toString();
|
|
25
|
+
if (typeof value !== "string") return null;
|
|
26
|
+
const normalized = value.trim();
|
|
27
|
+
return normalized.length > 0 ? normalized : null;
|
|
28
|
+
}
|
|
29
|
+
function asBoolean(value) {
|
|
30
|
+
if (typeof value === "boolean") return value;
|
|
31
|
+
if (typeof value === "number") return value !== 0;
|
|
32
|
+
if (typeof value === "string") {
|
|
33
|
+
return parseBooleanToken(value) ?? false;
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
function asBooleanOrNull(value) {
|
|
38
|
+
if (typeof value === "boolean") return value;
|
|
39
|
+
if (typeof value === "number") return value !== 0;
|
|
40
|
+
if (typeof value === "string") {
|
|
41
|
+
return parseBooleanToken(value);
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function asRecord(value) {
|
|
46
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
function asIdentifier(value) {
|
|
52
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
53
|
+
return String(value);
|
|
54
|
+
}
|
|
55
|
+
if (typeof value === "bigint") {
|
|
56
|
+
return value.toString();
|
|
57
|
+
}
|
|
58
|
+
return asString(value);
|
|
59
|
+
}
|
|
60
|
+
function firstString(record, keys) {
|
|
61
|
+
if (!record) return null;
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const value = asString(record[key]);
|
|
64
|
+
if (value) return value;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
function readTrimmedString(value) {
|
|
69
|
+
if (typeof value !== "string") return null;
|
|
70
|
+
const trimmed = value.trim();
|
|
71
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
72
|
+
}
|
|
73
|
+
function asNumber(value) {
|
|
74
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
75
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
76
|
+
const parsed = Number(value);
|
|
77
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
function asStringArray(value) {
|
|
82
|
+
if (!Array.isArray(value)) return [];
|
|
83
|
+
return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter((entry) => entry.length > 0);
|
|
84
|
+
}
|
|
85
|
+
|
|
13
86
|
// src/utils/parse-boolean-flag.ts
|
|
14
87
|
function parseBooleanFlag(rawValue, fallback) {
|
|
15
88
|
if (!rawValue) return fallback;
|
|
@@ -143,11 +216,69 @@ function proxyRequestHeaders(request) {
|
|
|
143
216
|
return headers;
|
|
144
217
|
}
|
|
145
218
|
|
|
219
|
+
// src/utils/sql-literals.ts
|
|
220
|
+
function getRandomBytes(size) {
|
|
221
|
+
const bytes = new Uint8Array(size);
|
|
222
|
+
const cryptoApi = globalThis.crypto;
|
|
223
|
+
if (cryptoApi?.getRandomValues) {
|
|
224
|
+
return cryptoApi.getRandomValues(bytes);
|
|
225
|
+
}
|
|
226
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
227
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
228
|
+
}
|
|
229
|
+
return bytes;
|
|
230
|
+
}
|
|
231
|
+
function bytesToHex(bytes) {
|
|
232
|
+
return Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("");
|
|
233
|
+
}
|
|
234
|
+
function createDollarQuoteTag(value) {
|
|
235
|
+
let tag = `s${bytesToHex(getRandomBytes(6))}`;
|
|
236
|
+
while (value.includes(`$${tag}$`)) {
|
|
237
|
+
tag = `${tag}_`;
|
|
238
|
+
}
|
|
239
|
+
return tag;
|
|
240
|
+
}
|
|
241
|
+
function sqlText(value) {
|
|
242
|
+
const tag = createDollarQuoteTag(value);
|
|
243
|
+
return `$${tag}$${value}$${tag}$`;
|
|
244
|
+
}
|
|
245
|
+
function escapeLikePatternValue(value) {
|
|
246
|
+
return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
247
|
+
}
|
|
248
|
+
function quoteSqlStringLiteral(value) {
|
|
249
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
250
|
+
}
|
|
251
|
+
function sqlNullableText(value) {
|
|
252
|
+
if (value == null) return "NULL";
|
|
253
|
+
return sqlText(value);
|
|
254
|
+
}
|
|
255
|
+
function sqlJsonbLiteral(value) {
|
|
256
|
+
return `${sqlText(JSON.stringify(value ?? null))}::jsonb`;
|
|
257
|
+
}
|
|
258
|
+
function sqlBigInt(value) {
|
|
259
|
+
return `${BigInt(value).toString()}::bigint`;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
exports.asBoolean = asBoolean;
|
|
263
|
+
exports.asBooleanOrNull = asBooleanOrNull;
|
|
264
|
+
exports.asIdentifier = asIdentifier;
|
|
265
|
+
exports.asNumber = asNumber;
|
|
266
|
+
exports.asRecord = asRecord;
|
|
267
|
+
exports.asString = asString;
|
|
268
|
+
exports.asStringArray = asStringArray;
|
|
146
269
|
exports.clearAuthCookies = clearAuthCookies;
|
|
270
|
+
exports.escapeLikePatternValue = escapeLikePatternValue;
|
|
271
|
+
exports.firstString = firstString;
|
|
147
272
|
exports.isLocalHostname = isLocalHostname;
|
|
148
273
|
exports.parseBooleanFlag = parseBooleanFlag;
|
|
149
274
|
exports.proxyRequestHeaders = proxyRequestHeaders;
|
|
275
|
+
exports.quoteSqlStringLiteral = quoteSqlStringLiteral;
|
|
276
|
+
exports.readTrimmedString = readTrimmedString;
|
|
150
277
|
exports.slugify = slugify;
|
|
278
|
+
exports.sqlBigInt = sqlBigInt;
|
|
279
|
+
exports.sqlJsonbLiteral = sqlJsonbLiteral;
|
|
280
|
+
exports.sqlNullableText = sqlNullableText;
|
|
281
|
+
exports.sqlText = sqlText;
|
|
151
282
|
exports.trimTrailingSlashes = trimTrailingSlashes;
|
|
152
283
|
//# sourceMappingURL=utils.cjs.map
|
|
153
284
|
//# sourceMappingURL=utils.cjs.map
|
package/dist/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/slugify.ts","../src/utils/trim-trailing-slashes.ts","../src/utils/parse-boolean-flag.ts","../src/utils/hostname.ts","../src/utils/auth-cookies.ts","../src/utils/proxy-request-headers.ts"],"names":[],"mappings":"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","file":"utils.cjs","sourcesContent":["export function slugify(input: string): string {\n return input\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","export function trimTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '')\n}\n","export function parseBooleanFlag(\n rawValue: string | undefined,\n fallback: boolean,\n): boolean {\n if (!rawValue) return fallback\n\n const normalized = rawValue.trim().toLowerCase()\n\n if (\n normalized === '1' ||\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === 'on'\n ) {\n return true\n }\n\n if (\n normalized === '0' ||\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === 'off'\n ) {\n return false\n }\n\n return fallback\n}\n","const LOCAL_IPV4_PATTERN = /^127(?:\\.\\d{1,3}){3}$/\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized) {\n return false\n }\n\n if (normalized === 'localhost' || normalized.endsWith('.localhost')) {\n return true\n }\n\n if (\n normalized === '127.0.0.1' ||\n LOCAL_IPV4_PATTERN.test(normalized) ||\n normalized === '::1' ||\n normalized === '[::1]' ||\n normalized === '0:0:0:0:0:0:0:1'\n ) {\n return true\n }\n\n return false\n}\n","import { isLocalHostname } from './hostname.ts'\n\nconst DEFAULT_AUTH_COOKIE_PREFIXES = [\n 'athena-auth',\n '__Secure-athena-auth',\n 'better-auth',\n '__Secure-better-auth',\n] as const\n\nexport interface ClearAuthCookiesOptions {\n prefixes?: string[]\n hostname?: string\n path?: string\n cookieHeader?: string\n}\n\ninterface BrowserCookieStore {\n cookie: string\n}\n\nfunction extractCookieNames(cookieHeader: string): string[] {\n const names = new Set<string>()\n for (const rawCookie of cookieHeader.split(';')) {\n const trimmed = rawCookie.trim()\n if (!trimmed) continue\n\n const eqPos = trimmed.indexOf('=')\n const name = (eqPos > -1 ? trimmed.slice(0, eqPos) : trimmed).trim()\n if (name) {\n names.add(name)\n }\n }\n return Array.from(names)\n}\n\nfunction buildCookieDomainCandidates(hostname: string): string[] {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized || isLocalHostname(normalized)) {\n return []\n }\n\n const labels = normalized.split('.').filter(Boolean)\n if (labels.length < 2) {\n return [normalized, `.${normalized}`]\n }\n\n const domains = new Set<string>()\n for (let index = 0; index <= labels.length - 2; index += 1) {\n const domain = labels.slice(index).join('.')\n domains.add(domain)\n domains.add(`.${domain}`)\n }\n return Array.from(domains)\n}\n\nfunction getCookieStore(): BrowserCookieStore | null {\n const candidate = (globalThis as { document?: BrowserCookieStore }).document\n if (!candidate || typeof candidate.cookie !== 'string') {\n return null\n }\n return candidate\n}\n\nfunction getRuntimeHostname(): string {\n const fromWindow = (\n globalThis as { window?: { location?: { hostname?: string } } }\n ).window?.location?.hostname\n if (typeof fromWindow === 'string') {\n return fromWindow\n }\n\n const fromLocation = (\n globalThis as { location?: { hostname?: string } }\n ).location?.hostname\n if (typeof fromLocation === 'string') {\n return fromLocation\n }\n\n return ''\n}\n\nfunction writeExpiredCookie(\n cookieStore: BrowserCookieStore,\n name: string,\n path: string,\n domain?: string,\n) {\n const domainClause = domain ? ` domain=${domain};` : ''\n cookieStore.cookie =\n `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; path=${path};${domainClause}`\n}\n\n/**\n * Clears Athena/Better Auth browser cookies by prefix.\n * Returns the cookie names that matched and were targeted for deletion.\n */\nexport function clearAuthCookies(options: ClearAuthCookiesOptions = {}): string[] {\n const cookieStore = getCookieStore()\n if (!cookieStore) {\n return []\n }\n\n const cookieHeader = options.cookieHeader ?? cookieStore.cookie\n if (!cookieHeader?.trim()) {\n return []\n }\n\n const prefixes = options.prefixes?.length ? options.prefixes : [...DEFAULT_AUTH_COOKIE_PREFIXES]\n const cookieNames = extractCookieNames(cookieHeader)\n const namesToClear = cookieNames.filter(name => prefixes.some(prefix => name.startsWith(prefix)))\n if (namesToClear.length === 0) {\n return []\n }\n\n const path = options.path?.trim() || '/'\n const hostname = options.hostname ?? getRuntimeHostname()\n const domainCandidates = buildCookieDomainCandidates(hostname)\n\n for (const name of namesToClear) {\n writeExpiredCookie(cookieStore, name, path)\n for (const domain of domainCandidates) {\n writeExpiredCookie(cookieStore, name, path, domain)\n }\n }\n\n return namesToClear\n}\n","export function proxyRequestHeaders(request: Request): Headers {\n const headers = new Headers(request.headers)\n const requestUrl = new URL(request.url)\n const proto = requestUrl.protocol.replace(/:$/u, '') || 'https'\n\n // Let fetch set the upstream Host header, but keep the original public app\n // origin available for auth servers that need to validate or generate links\n // for Vercel preview domains behind this proxy.\n headers.delete('host')\n headers.set('x-forwarded-host', requestUrl.host)\n headers.set('x-forwarded-proto', proto)\n headers.set('x-forwarded-origin', requestUrl.origin)\n headers.set('x-forwarded-uri', `${requestUrl.pathname}${requestUrl.search}`)\n\n if (requestUrl.port) {\n headers.set('x-forwarded-port', requestUrl.port)\n } else {\n headers.delete('x-forwarded-port')\n }\n\n return headers\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/slugify.ts","../src/utils/trim-trailing-slashes.ts","../src/utils/coercions.ts","../src/utils/parse-boolean-flag.ts","../src/utils/hostname.ts","../src/utils/auth-cookies.ts","../src/utils/proxy-request-headers.ts","../src/utils/sql-literals.ts"],"names":[],"mappings":"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","file":"utils.cjs","sourcesContent":["export function slugify(input: string): string {\n return input\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64)\n}\n","export function trimTrailingSlashes(value: string): string {\n return value.replace(/\\/+$/, '')\n}\n","const BOOLEAN_TRUE_TOKENS = new Set(['true', '1', 'yes', 'y', 'on'])\nconst BOOLEAN_FALSE_TOKENS = new Set(['false', '0', 'no', 'n', 'off'])\n\nfunction parseBooleanToken(value: string): boolean | null {\n const normalized = value.trim().toLowerCase()\n if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true\n if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false\n return null\n}\n\nexport function asString(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'bigint') return value.toString()\n if (typeof value !== 'string') return null\n\n const normalized = value.trim()\n return normalized.length > 0 ? normalized : null\n}\n\nexport function asBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value) ?? false\n }\n\n return false\n}\n\nexport function asBooleanOrNull(value: unknown): boolean | null {\n if (typeof value === 'boolean') return value\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') {\n return parseBooleanToken(value)\n }\n\n return null\n}\n\nexport function asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null\n }\n return value as Record<string, unknown>\n}\n\nexport function asIdentifier(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return String(value)\n }\n if (typeof value === 'bigint') {\n return value.toString()\n }\n return asString(value)\n}\n\nexport function firstString(\n record: Record<string, unknown> | null | undefined,\n keys: readonly string[],\n): string | null {\n if (!record) return null\n for (const key of keys) {\n const value = asString(record[key])\n if (value) return value\n }\n return null\n}\n\nexport function readTrimmedString(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length > 0 ? trimmed : null\n}\n\nexport function asNumber(value: unknown): number | null {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string' && value.trim().length > 0) {\n const parsed = Number(value)\n if (Number.isFinite(parsed)) return parsed\n }\n return null\n}\n\nexport function asStringArray(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map(entry => (typeof entry === 'string' ? entry.trim() : ''))\n .filter(entry => entry.length > 0)\n}\n","export function parseBooleanFlag(\n rawValue: string | undefined,\n fallback: boolean,\n): boolean {\n if (!rawValue) return fallback\n\n const normalized = rawValue.trim().toLowerCase()\n\n if (\n normalized === '1' ||\n normalized === 'true' ||\n normalized === 'yes' ||\n normalized === 'on'\n ) {\n return true\n }\n\n if (\n normalized === '0' ||\n normalized === 'false' ||\n normalized === 'no' ||\n normalized === 'off'\n ) {\n return false\n }\n\n return fallback\n}\n","const LOCAL_IPV4_PATTERN = /^127(?:\\.\\d{1,3}){3}$/\n\nexport function isLocalHostname(hostname: string): boolean {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized) {\n return false\n }\n\n if (normalized === 'localhost' || normalized.endsWith('.localhost')) {\n return true\n }\n\n if (\n normalized === '127.0.0.1' ||\n LOCAL_IPV4_PATTERN.test(normalized) ||\n normalized === '::1' ||\n normalized === '[::1]' ||\n normalized === '0:0:0:0:0:0:0:1'\n ) {\n return true\n }\n\n return false\n}\n","import { isLocalHostname } from './hostname.ts'\n\nconst DEFAULT_AUTH_COOKIE_PREFIXES = [\n 'athena-auth',\n '__Secure-athena-auth',\n 'better-auth',\n '__Secure-better-auth',\n] as const\n\nexport interface ClearAuthCookiesOptions {\n prefixes?: string[]\n hostname?: string\n path?: string\n cookieHeader?: string\n}\n\ninterface BrowserCookieStore {\n cookie: string\n}\n\nfunction extractCookieNames(cookieHeader: string): string[] {\n const names = new Set<string>()\n for (const rawCookie of cookieHeader.split(';')) {\n const trimmed = rawCookie.trim()\n if (!trimmed) continue\n\n const eqPos = trimmed.indexOf('=')\n const name = (eqPos > -1 ? trimmed.slice(0, eqPos) : trimmed).trim()\n if (name) {\n names.add(name)\n }\n }\n return Array.from(names)\n}\n\nfunction buildCookieDomainCandidates(hostname: string): string[] {\n const normalized = hostname.trim().replace(/\\.$/, '').toLowerCase()\n if (!normalized || isLocalHostname(normalized)) {\n return []\n }\n\n const labels = normalized.split('.').filter(Boolean)\n if (labels.length < 2) {\n return [normalized, `.${normalized}`]\n }\n\n const domains = new Set<string>()\n for (let index = 0; index <= labels.length - 2; index += 1) {\n const domain = labels.slice(index).join('.')\n domains.add(domain)\n domains.add(`.${domain}`)\n }\n return Array.from(domains)\n}\n\nfunction getCookieStore(): BrowserCookieStore | null {\n const candidate = (globalThis as { document?: BrowserCookieStore }).document\n if (!candidate || typeof candidate.cookie !== 'string') {\n return null\n }\n return candidate\n}\n\nfunction getRuntimeHostname(): string {\n const fromWindow = (\n globalThis as { window?: { location?: { hostname?: string } } }\n ).window?.location?.hostname\n if (typeof fromWindow === 'string') {\n return fromWindow\n }\n\n const fromLocation = (\n globalThis as { location?: { hostname?: string } }\n ).location?.hostname\n if (typeof fromLocation === 'string') {\n return fromLocation\n }\n\n return ''\n}\n\nfunction writeExpiredCookie(\n cookieStore: BrowserCookieStore,\n name: string,\n path: string,\n domain?: string,\n) {\n const domainClause = domain ? ` domain=${domain};` : ''\n cookieStore.cookie =\n `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; path=${path};${domainClause}`\n}\n\n/**\n * Clears Athena/Better Auth browser cookies by prefix.\n * Returns the cookie names that matched and were targeted for deletion.\n */\nexport function clearAuthCookies(options: ClearAuthCookiesOptions = {}): string[] {\n const cookieStore = getCookieStore()\n if (!cookieStore) {\n return []\n }\n\n const cookieHeader = options.cookieHeader ?? cookieStore.cookie\n if (!cookieHeader?.trim()) {\n return []\n }\n\n const prefixes = options.prefixes?.length ? options.prefixes : [...DEFAULT_AUTH_COOKIE_PREFIXES]\n const cookieNames = extractCookieNames(cookieHeader)\n const namesToClear = cookieNames.filter(name => prefixes.some(prefix => name.startsWith(prefix)))\n if (namesToClear.length === 0) {\n return []\n }\n\n const path = options.path?.trim() || '/'\n const hostname = options.hostname ?? getRuntimeHostname()\n const domainCandidates = buildCookieDomainCandidates(hostname)\n\n for (const name of namesToClear) {\n writeExpiredCookie(cookieStore, name, path)\n for (const domain of domainCandidates) {\n writeExpiredCookie(cookieStore, name, path, domain)\n }\n }\n\n return namesToClear\n}\n","export function proxyRequestHeaders(request: Request): Headers {\n const headers = new Headers(request.headers)\n const requestUrl = new URL(request.url)\n const proto = requestUrl.protocol.replace(/:$/u, '') || 'https'\n\n // Let fetch set the upstream Host header, but keep the original public app\n // origin available for auth servers that need to validate or generate links\n // for Vercel preview domains behind this proxy.\n headers.delete('host')\n headers.set('x-forwarded-host', requestUrl.host)\n headers.set('x-forwarded-proto', proto)\n headers.set('x-forwarded-origin', requestUrl.origin)\n headers.set('x-forwarded-uri', `${requestUrl.pathname}${requestUrl.search}`)\n\n if (requestUrl.port) {\n headers.set('x-forwarded-port', requestUrl.port)\n } else {\n headers.delete('x-forwarded-port')\n }\n\n return headers\n}\n","interface CryptoLike {\n getRandomValues<T extends ArrayBufferView | null>(array: T): T\n}\n\nfunction getRandomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size)\n const cryptoApi = (globalThis as { crypto?: CryptoLike }).crypto\n if (cryptoApi?.getRandomValues) {\n return cryptoApi.getRandomValues(bytes)\n }\n\n for (let index = 0; index < bytes.length; index += 1) {\n bytes[index] = Math.floor(Math.random() * 256)\n }\n return bytes\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes, value => value.toString(16).padStart(2, '0')).join('')\n}\n\nfunction createDollarQuoteTag(value: string): string {\n let tag = `s${bytesToHex(getRandomBytes(6))}`\n while (value.includes(`$${tag}$`)) {\n tag = `${tag}_`\n }\n return tag\n}\n\n/**\n * Wraps a string in a PostgreSQL dollar-quoted literal.\n *\n * Use this for SQL values, not identifiers. Pair with `identifier(...)`\n * for table/column names.\n */\nexport function sqlText(value: string): string {\n const tag = createDollarQuoteTag(value)\n return `$${tag}$${value}$${tag}$`\n}\n\n/**\n * Escapes `%`, `_`, and `\\` for SQL `LIKE` / `ILIKE` patterns.\n */\nexport function escapeLikePatternValue(value: string): string {\n return value\n .replaceAll('\\\\', '\\\\\\\\')\n .replaceAll('%', '\\\\%')\n .replaceAll('_', '\\\\_')\n}\n\n/**\n * Wraps a string in a single-quoted SQL string literal.\n *\n * Prefer `sqlText(...)` for arbitrary raw SQL values when possible.\n */\nexport function quoteSqlStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`\n}\n\n/**\n * Returns a dollar-quoted literal for strings, or the SQL keyword `NULL`\n * for nullish values.\n */\nexport function sqlNullableText(value: string | null | undefined): string {\n if (value == null) return 'NULL'\n return sqlText(value)\n}\n\n/**\n * Serializes a value and casts the result to `jsonb`.\n */\nexport function sqlJsonbLiteral(value: unknown): string {\n return `${sqlText(JSON.stringify(value ?? null))}::jsonb`\n}\n\n/**\n * Renders an explicit `bigint` SQL literal.\n */\nexport function sqlBigInt(value: bigint | number): string {\n return `${BigInt(value).toString()}::bigint`\n}\n"]}
|
package/dist/utils.d.cts
CHANGED
|
@@ -2,6 +2,16 @@ declare function slugify(input: string): string;
|
|
|
2
2
|
|
|
3
3
|
declare function trimTrailingSlashes(value: string): string;
|
|
4
4
|
|
|
5
|
+
declare function asString(value: unknown): string | null;
|
|
6
|
+
declare function asBoolean(value: unknown): boolean;
|
|
7
|
+
declare function asBooleanOrNull(value: unknown): boolean | null;
|
|
8
|
+
declare function asRecord(value: unknown): Record<string, unknown> | null;
|
|
9
|
+
declare function asIdentifier(value: unknown): string | null;
|
|
10
|
+
declare function firstString(record: Record<string, unknown> | null | undefined, keys: readonly string[]): string | null;
|
|
11
|
+
declare function readTrimmedString(value: unknown): string | null;
|
|
12
|
+
declare function asNumber(value: unknown): number | null;
|
|
13
|
+
declare function asStringArray(value: unknown): string[];
|
|
14
|
+
|
|
5
15
|
declare function parseBooleanFlag(rawValue: string | undefined, fallback: boolean): boolean;
|
|
6
16
|
|
|
7
17
|
declare function isLocalHostname(hostname: string): boolean;
|
|
@@ -20,4 +30,35 @@ declare function clearAuthCookies(options?: ClearAuthCookiesOptions): string[];
|
|
|
20
30
|
|
|
21
31
|
declare function proxyRequestHeaders(request: Request): Headers;
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Wraps a string in a PostgreSQL dollar-quoted literal.
|
|
35
|
+
*
|
|
36
|
+
* Use this for SQL values, not identifiers. Pair with `identifier(...)`
|
|
37
|
+
* for table/column names.
|
|
38
|
+
*/
|
|
39
|
+
declare function sqlText(value: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Escapes `%`, `_`, and `\` for SQL `LIKE` / `ILIKE` patterns.
|
|
42
|
+
*/
|
|
43
|
+
declare function escapeLikePatternValue(value: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Wraps a string in a single-quoted SQL string literal.
|
|
46
|
+
*
|
|
47
|
+
* Prefer `sqlText(...)` for arbitrary raw SQL values when possible.
|
|
48
|
+
*/
|
|
49
|
+
declare function quoteSqlStringLiteral(value: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a dollar-quoted literal for strings, or the SQL keyword `NULL`
|
|
52
|
+
* for nullish values.
|
|
53
|
+
*/
|
|
54
|
+
declare function sqlNullableText(value: string | null | undefined): string;
|
|
55
|
+
/**
|
|
56
|
+
* Serializes a value and casts the result to `jsonb`.
|
|
57
|
+
*/
|
|
58
|
+
declare function sqlJsonbLiteral(value: unknown): string;
|
|
59
|
+
/**
|
|
60
|
+
* Renders an explicit `bigint` SQL literal.
|
|
61
|
+
*/
|
|
62
|
+
declare function sqlBigInt(value: bigint | number): string;
|
|
63
|
+
|
|
64
|
+
export { type ClearAuthCookiesOptions, asBoolean, asBooleanOrNull, asIdentifier, asNumber, asRecord, asString, asStringArray, clearAuthCookies, escapeLikePatternValue, firstString, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readTrimmedString, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };
|
package/dist/utils.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ declare function slugify(input: string): string;
|
|
|
2
2
|
|
|
3
3
|
declare function trimTrailingSlashes(value: string): string;
|
|
4
4
|
|
|
5
|
+
declare function asString(value: unknown): string | null;
|
|
6
|
+
declare function asBoolean(value: unknown): boolean;
|
|
7
|
+
declare function asBooleanOrNull(value: unknown): boolean | null;
|
|
8
|
+
declare function asRecord(value: unknown): Record<string, unknown> | null;
|
|
9
|
+
declare function asIdentifier(value: unknown): string | null;
|
|
10
|
+
declare function firstString(record: Record<string, unknown> | null | undefined, keys: readonly string[]): string | null;
|
|
11
|
+
declare function readTrimmedString(value: unknown): string | null;
|
|
12
|
+
declare function asNumber(value: unknown): number | null;
|
|
13
|
+
declare function asStringArray(value: unknown): string[];
|
|
14
|
+
|
|
5
15
|
declare function parseBooleanFlag(rawValue: string | undefined, fallback: boolean): boolean;
|
|
6
16
|
|
|
7
17
|
declare function isLocalHostname(hostname: string): boolean;
|
|
@@ -20,4 +30,35 @@ declare function clearAuthCookies(options?: ClearAuthCookiesOptions): string[];
|
|
|
20
30
|
|
|
21
31
|
declare function proxyRequestHeaders(request: Request): Headers;
|
|
22
32
|
|
|
23
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Wraps a string in a PostgreSQL dollar-quoted literal.
|
|
35
|
+
*
|
|
36
|
+
* Use this for SQL values, not identifiers. Pair with `identifier(...)`
|
|
37
|
+
* for table/column names.
|
|
38
|
+
*/
|
|
39
|
+
declare function sqlText(value: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Escapes `%`, `_`, and `\` for SQL `LIKE` / `ILIKE` patterns.
|
|
42
|
+
*/
|
|
43
|
+
declare function escapeLikePatternValue(value: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* Wraps a string in a single-quoted SQL string literal.
|
|
46
|
+
*
|
|
47
|
+
* Prefer `sqlText(...)` for arbitrary raw SQL values when possible.
|
|
48
|
+
*/
|
|
49
|
+
declare function quoteSqlStringLiteral(value: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Returns a dollar-quoted literal for strings, or the SQL keyword `NULL`
|
|
52
|
+
* for nullish values.
|
|
53
|
+
*/
|
|
54
|
+
declare function sqlNullableText(value: string | null | undefined): string;
|
|
55
|
+
/**
|
|
56
|
+
* Serializes a value and casts the result to `jsonb`.
|
|
57
|
+
*/
|
|
58
|
+
declare function sqlJsonbLiteral(value: unknown): string;
|
|
59
|
+
/**
|
|
60
|
+
* Renders an explicit `bigint` SQL literal.
|
|
61
|
+
*/
|
|
62
|
+
declare function sqlBigInt(value: bigint | number): string;
|
|
63
|
+
|
|
64
|
+
export { type ClearAuthCookiesOptions, asBoolean, asBooleanOrNull, asIdentifier, asNumber, asRecord, asString, asStringArray, clearAuthCookies, escapeLikePatternValue, firstString, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readTrimmedString, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };
|
package/dist/utils.js
CHANGED
|
@@ -8,6 +8,79 @@ function trimTrailingSlashes(value) {
|
|
|
8
8
|
return value.replace(/\/+$/, "");
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
// src/utils/coercions.ts
|
|
12
|
+
var BOOLEAN_TRUE_TOKENS = /* @__PURE__ */ new Set(["true", "1", "yes", "y", "on"]);
|
|
13
|
+
var BOOLEAN_FALSE_TOKENS = /* @__PURE__ */ new Set(["false", "0", "no", "n", "off"]);
|
|
14
|
+
function parseBooleanToken(value) {
|
|
15
|
+
const normalized = value.trim().toLowerCase();
|
|
16
|
+
if (BOOLEAN_TRUE_TOKENS.has(normalized)) return true;
|
|
17
|
+
if (BOOLEAN_FALSE_TOKENS.has(normalized)) return false;
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function asString(value) {
|
|
21
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
22
|
+
if (typeof value === "bigint") return value.toString();
|
|
23
|
+
if (typeof value !== "string") return null;
|
|
24
|
+
const normalized = value.trim();
|
|
25
|
+
return normalized.length > 0 ? normalized : null;
|
|
26
|
+
}
|
|
27
|
+
function asBoolean(value) {
|
|
28
|
+
if (typeof value === "boolean") return value;
|
|
29
|
+
if (typeof value === "number") return value !== 0;
|
|
30
|
+
if (typeof value === "string") {
|
|
31
|
+
return parseBooleanToken(value) ?? false;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
function asBooleanOrNull(value) {
|
|
36
|
+
if (typeof value === "boolean") return value;
|
|
37
|
+
if (typeof value === "number") return value !== 0;
|
|
38
|
+
if (typeof value === "string") {
|
|
39
|
+
return parseBooleanToken(value);
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
function asRecord(value) {
|
|
44
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
function asIdentifier(value) {
|
|
50
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
51
|
+
return String(value);
|
|
52
|
+
}
|
|
53
|
+
if (typeof value === "bigint") {
|
|
54
|
+
return value.toString();
|
|
55
|
+
}
|
|
56
|
+
return asString(value);
|
|
57
|
+
}
|
|
58
|
+
function firstString(record, keys) {
|
|
59
|
+
if (!record) return null;
|
|
60
|
+
for (const key of keys) {
|
|
61
|
+
const value = asString(record[key]);
|
|
62
|
+
if (value) return value;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function readTrimmedString(value) {
|
|
67
|
+
if (typeof value !== "string") return null;
|
|
68
|
+
const trimmed = value.trim();
|
|
69
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
70
|
+
}
|
|
71
|
+
function asNumber(value) {
|
|
72
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
73
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
74
|
+
const parsed = Number(value);
|
|
75
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function asStringArray(value) {
|
|
80
|
+
if (!Array.isArray(value)) return [];
|
|
81
|
+
return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter((entry) => entry.length > 0);
|
|
82
|
+
}
|
|
83
|
+
|
|
11
84
|
// src/utils/parse-boolean-flag.ts
|
|
12
85
|
function parseBooleanFlag(rawValue, fallback) {
|
|
13
86
|
if (!rawValue) return fallback;
|
|
@@ -141,6 +214,49 @@ function proxyRequestHeaders(request) {
|
|
|
141
214
|
return headers;
|
|
142
215
|
}
|
|
143
216
|
|
|
144
|
-
|
|
217
|
+
// src/utils/sql-literals.ts
|
|
218
|
+
function getRandomBytes(size) {
|
|
219
|
+
const bytes = new Uint8Array(size);
|
|
220
|
+
const cryptoApi = globalThis.crypto;
|
|
221
|
+
if (cryptoApi?.getRandomValues) {
|
|
222
|
+
return cryptoApi.getRandomValues(bytes);
|
|
223
|
+
}
|
|
224
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
225
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
226
|
+
}
|
|
227
|
+
return bytes;
|
|
228
|
+
}
|
|
229
|
+
function bytesToHex(bytes) {
|
|
230
|
+
return Array.from(bytes, (value) => value.toString(16).padStart(2, "0")).join("");
|
|
231
|
+
}
|
|
232
|
+
function createDollarQuoteTag(value) {
|
|
233
|
+
let tag = `s${bytesToHex(getRandomBytes(6))}`;
|
|
234
|
+
while (value.includes(`$${tag}$`)) {
|
|
235
|
+
tag = `${tag}_`;
|
|
236
|
+
}
|
|
237
|
+
return tag;
|
|
238
|
+
}
|
|
239
|
+
function sqlText(value) {
|
|
240
|
+
const tag = createDollarQuoteTag(value);
|
|
241
|
+
return `$${tag}$${value}$${tag}$`;
|
|
242
|
+
}
|
|
243
|
+
function escapeLikePatternValue(value) {
|
|
244
|
+
return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
245
|
+
}
|
|
246
|
+
function quoteSqlStringLiteral(value) {
|
|
247
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
248
|
+
}
|
|
249
|
+
function sqlNullableText(value) {
|
|
250
|
+
if (value == null) return "NULL";
|
|
251
|
+
return sqlText(value);
|
|
252
|
+
}
|
|
253
|
+
function sqlJsonbLiteral(value) {
|
|
254
|
+
return `${sqlText(JSON.stringify(value ?? null))}::jsonb`;
|
|
255
|
+
}
|
|
256
|
+
function sqlBigInt(value) {
|
|
257
|
+
return `${BigInt(value).toString()}::bigint`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { asBoolean, asBooleanOrNull, asIdentifier, asNumber, asRecord, asString, asStringArray, clearAuthCookies, escapeLikePatternValue, firstString, isLocalHostname, parseBooleanFlag, proxyRequestHeaders, quoteSqlStringLiteral, readTrimmedString, slugify, sqlBigInt, sqlJsonbLiteral, sqlNullableText, sqlText, trimTrailingSlashes };
|
|
145
261
|
//# sourceMappingURL=utils.js.map
|
|
146
262
|
//# sourceMappingURL=utils.js.map
|