@an5/adapters 0.2.3 → 0.2.5
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 +305 -283
- package/{typescript → dist}/browser.d.ts +1 -1
- package/{typescript → dist}/browser.js +2 -1
- package/{typescript → dist}/index.d.ts +2 -0
- package/{typescript → dist}/index.js +6 -1
- package/dotnet/An5Adapter.cs +275 -275
- package/dotnet/Base/Core.cs +82 -82
- package/dotnet/Mssql/MssqlEngine.cs +144 -144
- package/dotnet/Postgres/PostgresEngine.cs +121 -121
- package/package.json +21 -11
- package/python/an5_adapter.py +97 -97
- package/python/base/__init__.py +3 -3
- package/python/base/dialects.py +8 -8
- package/python/base/metadata.py +10 -10
- package/python/base/sql.py +121 -121
- package/python/mssql/__init__.py +1 -1
- package/python/mssql/provider.py +62 -62
- package/python/postgres/__init__.py +1 -1
- package/python/postgres/provider.py +15 -15
- package/python/table_client.py +216 -216
- package/typescript/src/an5Adapter.ts +505 -505
- package/typescript/src/base/index.ts +3 -3
- package/typescript/src/base/metadata.ts +28 -28
- package/typescript/src/base/sql.ts +98 -98
- package/typescript/src/base/types.ts +24 -24
- package/typescript/src/browser.ts +6 -6
- package/typescript/src/config.ts +95 -95
- package/typescript/src/googlesheets/adapter.ts +259 -259
- package/typescript/src/googlesheets/an5SheetsAdapter.ts +3 -3
- package/typescript/src/googlesheets/config.ts +47 -47
- package/typescript/src/googlesheets/helpers.ts +143 -143
- package/typescript/src/googlesheets/index.ts +3 -3
- package/typescript/src/googlesheets/parseConnectionString.ts +46 -46
- package/typescript/src/googlesheets/retry.ts +126 -126
- package/typescript/src/googlesheets/sqlExecutor.ts +301 -301
- package/typescript/src/googlesheets/tableClient.ts +455 -455
- package/typescript/src/googlesheets/types.ts +6 -6
- package/typescript/src/index.ts +28 -19
- package/typescript/src/mssql/engine.ts +132 -132
- package/typescript/src/mssql/index.ts +1 -1
- package/typescript/src/mysql/engine.ts +80 -80
- package/typescript/src/mysql/index.ts +1 -1
- package/typescript/src/postgres/engine.ts +87 -87
- package/typescript/src/postgres/index.ts +1 -1
- package/typescript/src/sqlite/engine.ts +55 -55
- package/typescript/src/sqlite/index.ts +1 -1
- /package/{typescript → dist}/an5Adapter.d.ts +0 -0
- /package/{typescript → dist}/an5Adapter.js +0 -0
- /package/{typescript → dist}/base/index.d.ts +0 -0
- /package/{typescript → dist}/base/index.js +0 -0
- /package/{typescript → dist}/base/metadata.d.ts +0 -0
- /package/{typescript → dist}/base/metadata.js +0 -0
- /package/{typescript → dist}/base/sql.d.ts +0 -0
- /package/{typescript → dist}/base/sql.js +0 -0
- /package/{typescript → dist}/base/types.d.ts +0 -0
- /package/{typescript → dist}/base/types.js +0 -0
- /package/{typescript → dist}/base/uuid.d.ts +0 -0
- /package/{typescript → dist}/base/uuid.js +0 -0
- /package/{typescript → dist}/config.d.ts +0 -0
- /package/{typescript → dist}/config.js +0 -0
- /package/{typescript → dist}/googlesheets/adapter.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/adapter.js +0 -0
- /package/{typescript → dist}/googlesheets/an5SheetsAdapter.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/an5SheetsAdapter.js +0 -0
- /package/{typescript → dist}/googlesheets/config.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/config.js +0 -0
- /package/{typescript → dist}/googlesheets/helpers.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/helpers.js +0 -0
- /package/{typescript → dist}/googlesheets/index.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/index.js +0 -0
- /package/{typescript → dist}/googlesheets/parseConnectionString.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/parseConnectionString.js +0 -0
- /package/{typescript → dist}/googlesheets/retry.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/retry.js +0 -0
- /package/{typescript → dist}/googlesheets/sqlExecutor.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/sqlExecutor.js +0 -0
- /package/{typescript → dist}/googlesheets/tableClient.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/tableClient.js +0 -0
- /package/{typescript → dist}/googlesheets/types.d.ts +0 -0
- /package/{typescript → dist}/googlesheets/types.js +0 -0
- /package/{typescript → dist}/mssql/engine.d.ts +0 -0
- /package/{typescript → dist}/mssql/engine.js +0 -0
- /package/{typescript → dist}/mssql/index.d.ts +0 -0
- /package/{typescript → dist}/mssql/index.js +0 -0
- /package/{typescript → dist}/mysql/engine.d.ts +0 -0
- /package/{typescript → dist}/mysql/engine.js +0 -0
- /package/{typescript → dist}/mysql/index.d.ts +0 -0
- /package/{typescript → dist}/mysql/index.js +0 -0
- /package/{typescript → dist}/postgres/engine.d.ts +0 -0
- /package/{typescript → dist}/postgres/engine.js +0 -0
- /package/{typescript → dist}/postgres/index.d.ts +0 -0
- /package/{typescript → dist}/postgres/index.js +0 -0
- /package/{typescript → dist}/sqlite/engine.d.ts +0 -0
- /package/{typescript → dist}/sqlite/engine.js +0 -0
- /package/{typescript → dist}/sqlite/index.d.ts +0 -0
- /package/{typescript → dist}/sqlite/index.js +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './sql';
|
|
3
|
-
export * from './metadata';
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './sql';
|
|
3
|
+
export * from './metadata';
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
export interface ModelFieldMeta {
|
|
2
|
-
name?: string;
|
|
3
|
-
ts?: string;
|
|
4
|
-
sql?: string;
|
|
5
|
-
isId?: boolean;
|
|
6
|
-
[key: string]: any;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface AdapterMetadata {
|
|
10
|
-
modelToTable?: Record<string, string>;
|
|
11
|
-
modelFields?: Record<string, any>;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
let modelToTable: Record<string, string> = {};
|
|
15
|
-
let modelFields: Record<string, any> = {};
|
|
16
|
-
|
|
17
|
-
export function setAdapterMetadata(metadata: AdapterMetadata): void {
|
|
18
|
-
modelToTable = { ...(metadata.modelToTable || {}) };
|
|
19
|
-
modelFields = { ...(metadata.modelFields || {}) };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function getModelToTable(): Record<string, string> {
|
|
23
|
-
return modelToTable;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getFieldsForModel(modelName: string): any {
|
|
27
|
-
return modelFields[modelName] || {};
|
|
28
|
-
}
|
|
1
|
+
export interface ModelFieldMeta {
|
|
2
|
+
name?: string;
|
|
3
|
+
ts?: string;
|
|
4
|
+
sql?: string;
|
|
5
|
+
isId?: boolean;
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AdapterMetadata {
|
|
10
|
+
modelToTable?: Record<string, string>;
|
|
11
|
+
modelFields?: Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let modelToTable: Record<string, string> = {};
|
|
15
|
+
let modelFields: Record<string, any> = {};
|
|
16
|
+
|
|
17
|
+
export function setAdapterMetadata(metadata: AdapterMetadata): void {
|
|
18
|
+
modelToTable = { ...(metadata.modelToTable || {}) };
|
|
19
|
+
modelFields = { ...(metadata.modelFields || {}) };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getModelToTable(): Record<string, string> {
|
|
23
|
+
return modelToTable;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getFieldsForModel(modelName: string): any {
|
|
27
|
+
return modelFields[modelName] || {};
|
|
28
|
+
}
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
import type { Dialect } from './types';
|
|
2
|
-
|
|
3
|
-
// ─── Quoting ───────────────────────────────────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
export function quote(name: string, dialect: Dialect): string {
|
|
6
|
-
if (dialect === 'postgres') {
|
|
7
|
-
if (name.startsWith('[') && name.endsWith(']')) return `"${name.slice(1, -1)}"`;
|
|
8
|
-
if (name.startsWith('"')) return name;
|
|
9
|
-
return `"${name}"`;
|
|
10
|
-
}
|
|
11
|
-
if (dialect === 'mysql') {
|
|
12
|
-
if (name.startsWith('[') && name.endsWith(']')) return `\`${name.slice(1, -1)}\``;
|
|
13
|
-
if (name.startsWith('`')) return name;
|
|
14
|
-
return `\`${name}\``;
|
|
15
|
-
}
|
|
16
|
-
// mssql / sqlite
|
|
17
|
-
return name.startsWith('[') ? name : `[${name}]`;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// ─── Where clause builder ──────────────────────────────────────────────────────────
|
|
21
|
-
|
|
22
|
-
export function parseWhere(modelName: string, where: any, params: Record<string, any>, dialect: Dialect, prefix = ''): string {
|
|
23
|
-
if (!where) return '';
|
|
24
|
-
const conditions: string[] = [];
|
|
25
|
-
|
|
26
|
-
const cleanWhere: Record<string, any> = {};
|
|
27
|
-
for (const [key, value] of Object.entries(where)) {
|
|
28
|
-
if (
|
|
29
|
-
key.includes('_') &&
|
|
30
|
-
value && typeof value === 'object' &&
|
|
31
|
-
!(value instanceof Date) &&
|
|
32
|
-
!(value as any).in && !(value as any).contains &&
|
|
33
|
-
!(value as any).not && !(value as any).gte &&
|
|
34
|
-
!(value as any).lte && !(value as any).gt && !(value as any).lt
|
|
35
|
-
) {
|
|
36
|
-
Object.assign(cleanWhere, value);
|
|
37
|
-
} else {
|
|
38
|
-
cleanWhere[key] = value;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
for (const [key, value] of Object.entries(cleanWhere)) {
|
|
43
|
-
if (key === 'OR' && Array.isArray(value)) {
|
|
44
|
-
const sub = value.map((v, i) => parseWhere(modelName, v, params, dialect, `${prefix}or_${i}_`)).filter(Boolean);
|
|
45
|
-
if (sub.length > 0) conditions.push(`(${sub.join(' OR ')})`);
|
|
46
|
-
} else if (key === 'AND' && Array.isArray(value)) {
|
|
47
|
-
const sub = value.map((v, i) => parseWhere(modelName, v, params, dialect, `${prefix}and_${i}_`)).filter(Boolean);
|
|
48
|
-
if (sub.length > 0) conditions.push(`(${sub.join(' AND ')})`);
|
|
49
|
-
} else {
|
|
50
|
-
const pname = `${prefix}${key}`;
|
|
51
|
-
const col = quote(key, dialect);
|
|
52
|
-
|
|
53
|
-
if (value === null) {
|
|
54
|
-
conditions.push(`${col} IS NULL`);
|
|
55
|
-
} else if (typeof value === 'object' && !(value instanceof Date)) {
|
|
56
|
-
const v = value as any;
|
|
57
|
-
if (v.not !== undefined) {
|
|
58
|
-
if (v.not === null) { conditions.push(`${col} IS NOT NULL`); }
|
|
59
|
-
else { const p = `${pname}_not`; params[p] = v.not; conditions.push(`${col} <> @${p}`); }
|
|
60
|
-
}
|
|
61
|
-
if (v.equals !== undefined) { const p = `${pname}_eq`; params[p] = v.equals; conditions.push(`${col} = @${p}`); }
|
|
62
|
-
if (v.contains !== undefined) { const p = `${pname}_co`; params[p] = `%${v.contains}%`; conditions.push(`${col} LIKE @${p}`); }
|
|
63
|
-
if (v.startsWith !== undefined) { const p = `${pname}_sw`; params[p] = `${v.startsWith}%`; conditions.push(`${col} LIKE @${p}`); }
|
|
64
|
-
if (v.endsWith !== undefined) { const p = `${pname}_ew`; params[p] = `%${v.endsWith}`; conditions.push(`${col} LIKE @${p}`); }
|
|
65
|
-
if (v.gte !== undefined) { const p = `${pname}_gte`; params[p] = v.gte; conditions.push(`${col} >= @${p}`); }
|
|
66
|
-
if (v.lte !== undefined) { const p = `${pname}_lte`; params[p] = v.lte; conditions.push(`${col} <= @${p}`); }
|
|
67
|
-
if (v.gt !== undefined) { const p = `${pname}_gt`; params[p] = v.gt; conditions.push(`${col} > @${p}`); }
|
|
68
|
-
if (v.lt !== undefined) { const p = `${pname}_lt`; params[p] = v.lt; conditions.push(`${col} < @${p}`); }
|
|
69
|
-
if (v.in !== undefined) {
|
|
70
|
-
if (Array.isArray(v.in) && v.in.length > 0) {
|
|
71
|
-
const ps = v.in.map((x: any, i: number) => { const p = `${pname}_in${i}`; params[p] = x; return `@${p}`; });
|
|
72
|
-
conditions.push(`${col} IN (${ps.join(', ')})`);
|
|
73
|
-
} else {
|
|
74
|
-
conditions.push('1=0');
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
params[pname] = value;
|
|
79
|
-
conditions.push(`${col} = @${pname}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return conditions.join(' AND ');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// ─── Order by builder ──────────────────────────────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
export function buildOrderBy(orderBy: any, dialect: Dialect): string {
|
|
89
|
-
if (!orderBy) return '';
|
|
90
|
-
const entries = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
91
|
-
const parts: string[] = [];
|
|
92
|
-
for (const entry of entries) {
|
|
93
|
-
for (const [key, dir] of Object.entries(entry)) {
|
|
94
|
-
parts.push(`${quote(key, dialect)} ${(dir as string).toUpperCase()}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
return parts.length > 0 ? `ORDER BY ${parts.join(', ')}` : '';
|
|
98
|
-
}
|
|
1
|
+
import type { Dialect } from './types';
|
|
2
|
+
|
|
3
|
+
// ─── Quoting ───────────────────────────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export function quote(name: string, dialect: Dialect): string {
|
|
6
|
+
if (dialect === 'postgres') {
|
|
7
|
+
if (name.startsWith('[') && name.endsWith(']')) return `"${name.slice(1, -1)}"`;
|
|
8
|
+
if (name.startsWith('"')) return name;
|
|
9
|
+
return `"${name}"`;
|
|
10
|
+
}
|
|
11
|
+
if (dialect === 'mysql') {
|
|
12
|
+
if (name.startsWith('[') && name.endsWith(']')) return `\`${name.slice(1, -1)}\``;
|
|
13
|
+
if (name.startsWith('`')) return name;
|
|
14
|
+
return `\`${name}\``;
|
|
15
|
+
}
|
|
16
|
+
// mssql / sqlite
|
|
17
|
+
return name.startsWith('[') ? name : `[${name}]`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ─── Where clause builder ──────────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
export function parseWhere(modelName: string, where: any, params: Record<string, any>, dialect: Dialect, prefix = ''): string {
|
|
23
|
+
if (!where) return '';
|
|
24
|
+
const conditions: string[] = [];
|
|
25
|
+
|
|
26
|
+
const cleanWhere: Record<string, any> = {};
|
|
27
|
+
for (const [key, value] of Object.entries(where)) {
|
|
28
|
+
if (
|
|
29
|
+
key.includes('_') &&
|
|
30
|
+
value && typeof value === 'object' &&
|
|
31
|
+
!(value instanceof Date) &&
|
|
32
|
+
!(value as any).in && !(value as any).contains &&
|
|
33
|
+
!(value as any).not && !(value as any).gte &&
|
|
34
|
+
!(value as any).lte && !(value as any).gt && !(value as any).lt
|
|
35
|
+
) {
|
|
36
|
+
Object.assign(cleanWhere, value);
|
|
37
|
+
} else {
|
|
38
|
+
cleanWhere[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const [key, value] of Object.entries(cleanWhere)) {
|
|
43
|
+
if (key === 'OR' && Array.isArray(value)) {
|
|
44
|
+
const sub = value.map((v, i) => parseWhere(modelName, v, params, dialect, `${prefix}or_${i}_`)).filter(Boolean);
|
|
45
|
+
if (sub.length > 0) conditions.push(`(${sub.join(' OR ')})`);
|
|
46
|
+
} else if (key === 'AND' && Array.isArray(value)) {
|
|
47
|
+
const sub = value.map((v, i) => parseWhere(modelName, v, params, dialect, `${prefix}and_${i}_`)).filter(Boolean);
|
|
48
|
+
if (sub.length > 0) conditions.push(`(${sub.join(' AND ')})`);
|
|
49
|
+
} else {
|
|
50
|
+
const pname = `${prefix}${key}`;
|
|
51
|
+
const col = quote(key, dialect);
|
|
52
|
+
|
|
53
|
+
if (value === null) {
|
|
54
|
+
conditions.push(`${col} IS NULL`);
|
|
55
|
+
} else if (typeof value === 'object' && !(value instanceof Date)) {
|
|
56
|
+
const v = value as any;
|
|
57
|
+
if (v.not !== undefined) {
|
|
58
|
+
if (v.not === null) { conditions.push(`${col} IS NOT NULL`); }
|
|
59
|
+
else { const p = `${pname}_not`; params[p] = v.not; conditions.push(`${col} <> @${p}`); }
|
|
60
|
+
}
|
|
61
|
+
if (v.equals !== undefined) { const p = `${pname}_eq`; params[p] = v.equals; conditions.push(`${col} = @${p}`); }
|
|
62
|
+
if (v.contains !== undefined) { const p = `${pname}_co`; params[p] = `%${v.contains}%`; conditions.push(`${col} LIKE @${p}`); }
|
|
63
|
+
if (v.startsWith !== undefined) { const p = `${pname}_sw`; params[p] = `${v.startsWith}%`; conditions.push(`${col} LIKE @${p}`); }
|
|
64
|
+
if (v.endsWith !== undefined) { const p = `${pname}_ew`; params[p] = `%${v.endsWith}`; conditions.push(`${col} LIKE @${p}`); }
|
|
65
|
+
if (v.gte !== undefined) { const p = `${pname}_gte`; params[p] = v.gte; conditions.push(`${col} >= @${p}`); }
|
|
66
|
+
if (v.lte !== undefined) { const p = `${pname}_lte`; params[p] = v.lte; conditions.push(`${col} <= @${p}`); }
|
|
67
|
+
if (v.gt !== undefined) { const p = `${pname}_gt`; params[p] = v.gt; conditions.push(`${col} > @${p}`); }
|
|
68
|
+
if (v.lt !== undefined) { const p = `${pname}_lt`; params[p] = v.lt; conditions.push(`${col} < @${p}`); }
|
|
69
|
+
if (v.in !== undefined) {
|
|
70
|
+
if (Array.isArray(v.in) && v.in.length > 0) {
|
|
71
|
+
const ps = v.in.map((x: any, i: number) => { const p = `${pname}_in${i}`; params[p] = x; return `@${p}`; });
|
|
72
|
+
conditions.push(`${col} IN (${ps.join(', ')})`);
|
|
73
|
+
} else {
|
|
74
|
+
conditions.push('1=0');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
params[pname] = value;
|
|
79
|
+
conditions.push(`${col} = @${pname}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return conditions.join(' AND ');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ─── Order by builder ──────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
export function buildOrderBy(orderBy: any, dialect: Dialect): string {
|
|
89
|
+
if (!orderBy) return '';
|
|
90
|
+
const entries = Array.isArray(orderBy) ? orderBy : [orderBy];
|
|
91
|
+
const parts: string[] = [];
|
|
92
|
+
for (const entry of entries) {
|
|
93
|
+
for (const [key, dir] of Object.entries(entry)) {
|
|
94
|
+
parts.push(`${quote(key, dialect)} ${(dir as string).toUpperCase()}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return parts.length > 0 ? `ORDER BY ${parts.join(', ')}` : '';
|
|
98
|
+
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
export type Dialect = 'mssql' | 'postgres' | 'mysql' | 'sqlite' | 'googlesheets';
|
|
2
|
-
|
|
3
|
-
export interface An5AdapterConfig {
|
|
4
|
-
connectionString: string;
|
|
5
|
-
poolMax?: number;
|
|
6
|
-
requestTimeout?: number;
|
|
7
|
-
connectionTimeout?: number;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface TransactionHandle {
|
|
11
|
-
exec<T>(query: string, params?: Record<string, any>): Promise<T[]>;
|
|
12
|
-
executeRaw(query: string, params?: Record<string, any>): Promise<number>;
|
|
13
|
-
commit(): Promise<void>;
|
|
14
|
-
rollback(): Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface QueryEngine {
|
|
18
|
-
dialect: Dialect;
|
|
19
|
-
exec<T>(query: string, params?: Record<string, any>): Promise<T[]>;
|
|
20
|
-
executeRaw(query: string, params?: Record<string, any>): Promise<number>;
|
|
21
|
-
connect(): Promise<void>;
|
|
22
|
-
disconnect(): Promise<void>;
|
|
23
|
-
beginTransaction(): Promise<TransactionHandle>;
|
|
24
|
-
}
|
|
1
|
+
export type Dialect = 'mssql' | 'postgres' | 'mysql' | 'sqlite' | 'googlesheets';
|
|
2
|
+
|
|
3
|
+
export interface An5AdapterConfig {
|
|
4
|
+
connectionString: string;
|
|
5
|
+
poolMax?: number;
|
|
6
|
+
requestTimeout?: number;
|
|
7
|
+
connectionTimeout?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface TransactionHandle {
|
|
11
|
+
exec<T>(query: string, params?: Record<string, any>): Promise<T[]>;
|
|
12
|
+
executeRaw(query: string, params?: Record<string, any>): Promise<number>;
|
|
13
|
+
commit(): Promise<void>;
|
|
14
|
+
rollback(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface QueryEngine {
|
|
18
|
+
dialect: Dialect;
|
|
19
|
+
exec<T>(query: string, params?: Record<string, any>): Promise<T[]>;
|
|
20
|
+
executeRaw(query: string, params?: Record<string, any>): Promise<number>;
|
|
21
|
+
connect(): Promise<void>;
|
|
22
|
+
disconnect(): Promise<void>;
|
|
23
|
+
beginTransaction(): Promise<TransactionHandle>;
|
|
24
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Browser-safe entry — no SQL engine imports
|
|
2
|
-
export { An5SheetsAdapter, SheetsTableClient, createAn5SheetsAdapter } from './googlesheets';
|
|
3
|
-
export type { An5SheetsAdapterConfig } from './googlesheets';
|
|
4
|
-
export type { An5AdapterConfig, Dialect } from './base/types';
|
|
5
|
-
export { getFieldsForModel, getModelToTable, setAdapterMetadata } from './base/metadata';
|
|
6
|
-
export type { AdapterMetadata } from './base/metadata';
|
|
1
|
+
// Browser-safe entry — no SQL engine imports
|
|
2
|
+
export { An5SheetsAdapter, SheetsTableClient, createAn5SheetsAdapter, parseSheetsConnectionString } from './googlesheets';
|
|
3
|
+
export type { An5SheetsAdapterConfig } from './googlesheets';
|
|
4
|
+
export type { An5AdapterConfig, Dialect } from './base/types';
|
|
5
|
+
export { getFieldsForModel, getModelToTable, setAdapterMetadata } from './base/metadata';
|
|
6
|
+
export type { AdapterMetadata } from './base/metadata';
|
package/typescript/src/config.ts
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { createAn5Adapter, type AnyAdapter } from './an5Adapter';
|
|
2
|
-
|
|
3
|
-
export interface LlmConfigData {
|
|
4
|
-
provider: string;
|
|
5
|
-
apiKey: string;
|
|
6
|
-
model?: string;
|
|
7
|
-
endpoint?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface EmbeddingConfigData {
|
|
11
|
-
provider: string;
|
|
12
|
-
apiKey: string;
|
|
13
|
-
model?: string;
|
|
14
|
-
endpoint?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
let _adapter: AnyAdapter | null = null;
|
|
18
|
-
|
|
19
|
-
function getAdapter(): AnyAdapter | null {
|
|
20
|
-
if (_adapter) return _adapter;
|
|
21
|
-
const url = process.env.DATABASE_URL;
|
|
22
|
-
if (!url) return null;
|
|
23
|
-
try {
|
|
24
|
-
_adapter = createAn5Adapter({ connectionString: url });
|
|
25
|
-
return _adapter;
|
|
26
|
-
} catch {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function resetAdapter(): void {
|
|
32
|
-
_adapter = null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function getLlmConfig(): Promise<LlmConfigData | null> {
|
|
36
|
-
const adapter = getAdapter();
|
|
37
|
-
if (!adapter) return null;
|
|
38
|
-
try {
|
|
39
|
-
const rows = await adapter.table<LlmConfigData>('LlmConfig').findMany({
|
|
40
|
-
where: { isActive: true },
|
|
41
|
-
});
|
|
42
|
-
if (rows.length > 0) {
|
|
43
|
-
const c = rows[0] as any;
|
|
44
|
-
return { provider: c.provider, apiKey: c.apiKey, model: c.model, endpoint: c.endpoint };
|
|
45
|
-
}
|
|
46
|
-
} catch {}
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function setLlmConfig(data: LlmConfigData): Promise<void> {
|
|
51
|
-
const adapter = getAdapter();
|
|
52
|
-
if (!adapter) throw new Error('DATABASE_URL not configured');
|
|
53
|
-
const existing = await adapter.table('LlmConfig').findFirst({ where: { isActive: true } });
|
|
54
|
-
if (existing) {
|
|
55
|
-
await adapter.table('LlmConfig').update({
|
|
56
|
-
where: { id: (existing as any).id },
|
|
57
|
-
data: { ...data, updatedAt: new Date() },
|
|
58
|
-
});
|
|
59
|
-
} else {
|
|
60
|
-
await adapter.table('LlmConfig').create({
|
|
61
|
-
data: { ...data, isActive: true, createdAt: new Date(), updatedAt: new Date() },
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export async function getEmbeddingConfig(): Promise<EmbeddingConfigData | null> {
|
|
67
|
-
const adapter = getAdapter();
|
|
68
|
-
if (!adapter) return null;
|
|
69
|
-
try {
|
|
70
|
-
const rows = await adapter.table<EmbeddingConfigData>('EmbeddingConfig').findMany({
|
|
71
|
-
where: { isActive: true },
|
|
72
|
-
});
|
|
73
|
-
if (rows.length > 0) {
|
|
74
|
-
const c = rows[0] as any;
|
|
75
|
-
return { provider: c.provider, apiKey: c.apiKey, model: c.model, endpoint: c.endpoint };
|
|
76
|
-
}
|
|
77
|
-
} catch {}
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function setEmbeddingConfig(data: EmbeddingConfigData): Promise<void> {
|
|
82
|
-
const adapter = getAdapter();
|
|
83
|
-
if (!adapter) throw new Error('DATABASE_URL not configured');
|
|
84
|
-
const existing = await adapter.table('EmbeddingConfig').findFirst({ where: { isActive: true } });
|
|
85
|
-
if (existing) {
|
|
86
|
-
await adapter.table('EmbeddingConfig').update({
|
|
87
|
-
where: { id: (existing as any).id },
|
|
88
|
-
data: { ...data, updatedAt: new Date() },
|
|
89
|
-
});
|
|
90
|
-
} else {
|
|
91
|
-
await adapter.table('EmbeddingConfig').create({
|
|
92
|
-
data: { ...data, isActive: true, createdAt: new Date(), updatedAt: new Date() },
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
1
|
+
import { createAn5Adapter, type AnyAdapter } from './an5Adapter';
|
|
2
|
+
|
|
3
|
+
export interface LlmConfigData {
|
|
4
|
+
provider: string;
|
|
5
|
+
apiKey: string;
|
|
6
|
+
model?: string;
|
|
7
|
+
endpoint?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface EmbeddingConfigData {
|
|
11
|
+
provider: string;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
endpoint?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let _adapter: AnyAdapter | null = null;
|
|
18
|
+
|
|
19
|
+
function getAdapter(): AnyAdapter | null {
|
|
20
|
+
if (_adapter) return _adapter;
|
|
21
|
+
const url = process.env.DATABASE_URL;
|
|
22
|
+
if (!url) return null;
|
|
23
|
+
try {
|
|
24
|
+
_adapter = createAn5Adapter({ connectionString: url });
|
|
25
|
+
return _adapter;
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function resetAdapter(): void {
|
|
32
|
+
_adapter = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function getLlmConfig(): Promise<LlmConfigData | null> {
|
|
36
|
+
const adapter = getAdapter();
|
|
37
|
+
if (!adapter) return null;
|
|
38
|
+
try {
|
|
39
|
+
const rows = await adapter.table<LlmConfigData>('LlmConfig').findMany({
|
|
40
|
+
where: { isActive: true },
|
|
41
|
+
});
|
|
42
|
+
if (rows.length > 0) {
|
|
43
|
+
const c = rows[0] as any;
|
|
44
|
+
return { provider: c.provider, apiKey: c.apiKey, model: c.model, endpoint: c.endpoint };
|
|
45
|
+
}
|
|
46
|
+
} catch {}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function setLlmConfig(data: LlmConfigData): Promise<void> {
|
|
51
|
+
const adapter = getAdapter();
|
|
52
|
+
if (!adapter) throw new Error('DATABASE_URL not configured');
|
|
53
|
+
const existing = await adapter.table('LlmConfig').findFirst({ where: { isActive: true } });
|
|
54
|
+
if (existing) {
|
|
55
|
+
await adapter.table('LlmConfig').update({
|
|
56
|
+
where: { id: (existing as any).id },
|
|
57
|
+
data: { ...data, updatedAt: new Date() },
|
|
58
|
+
});
|
|
59
|
+
} else {
|
|
60
|
+
await adapter.table('LlmConfig').create({
|
|
61
|
+
data: { ...data, isActive: true, createdAt: new Date(), updatedAt: new Date() },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function getEmbeddingConfig(): Promise<EmbeddingConfigData | null> {
|
|
67
|
+
const adapter = getAdapter();
|
|
68
|
+
if (!adapter) return null;
|
|
69
|
+
try {
|
|
70
|
+
const rows = await adapter.table<EmbeddingConfigData>('EmbeddingConfig').findMany({
|
|
71
|
+
where: { isActive: true },
|
|
72
|
+
});
|
|
73
|
+
if (rows.length > 0) {
|
|
74
|
+
const c = rows[0] as any;
|
|
75
|
+
return { provider: c.provider, apiKey: c.apiKey, model: c.model, endpoint: c.endpoint };
|
|
76
|
+
}
|
|
77
|
+
} catch {}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export async function setEmbeddingConfig(data: EmbeddingConfigData): Promise<void> {
|
|
82
|
+
const adapter = getAdapter();
|
|
83
|
+
if (!adapter) throw new Error('DATABASE_URL not configured');
|
|
84
|
+
const existing = await adapter.table('EmbeddingConfig').findFirst({ where: { isActive: true } });
|
|
85
|
+
if (existing) {
|
|
86
|
+
await adapter.table('EmbeddingConfig').update({
|
|
87
|
+
where: { id: (existing as any).id },
|
|
88
|
+
data: { ...data, updatedAt: new Date() },
|
|
89
|
+
});
|
|
90
|
+
} else {
|
|
91
|
+
await adapter.table('EmbeddingConfig').create({
|
|
92
|
+
data: { ...data, isActive: true, createdAt: new Date(), updatedAt: new Date() },
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|