postgresdk 0.16.0 → 0.16.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/dist/cli.js +58 -5
- package/dist/index.js +58 -5
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1051,6 +1051,8 @@ function postgresTypeToTsType(column, enums) {
|
|
|
1051
1051
|
case "_int8":
|
|
1052
1052
|
case "_integer":
|
|
1053
1053
|
return "number[]";
|
|
1054
|
+
case "vector":
|
|
1055
|
+
return "number[]";
|
|
1054
1056
|
default:
|
|
1055
1057
|
return "string";
|
|
1056
1058
|
}
|
|
@@ -1204,6 +1206,8 @@ function postgresTypeToJsonType(pgType, enums) {
|
|
|
1204
1206
|
case "_int8":
|
|
1205
1207
|
case "_integer":
|
|
1206
1208
|
return "number[]";
|
|
1209
|
+
case "vector":
|
|
1210
|
+
return "number[]";
|
|
1207
1211
|
default:
|
|
1208
1212
|
return "string";
|
|
1209
1213
|
}
|
|
@@ -1397,6 +1401,12 @@ function generateUnifiedContractMarkdown(contract) {
|
|
|
1397
1401
|
lines.push("| `$ilike` | Pattern match (case-insensitive) | `{ email: { $ilike: '%@GMAIL%' } }` | String |");
|
|
1398
1402
|
lines.push("| `$is` | IS NULL | `{ deleted_at: { $is: null } }` | Nullable fields |");
|
|
1399
1403
|
lines.push("| `$isNot` | IS NOT NULL | `{ created_by: { $isNot: null } }` | Nullable fields |");
|
|
1404
|
+
lines.push("| `$jsonbContains` | JSONB contains | `{ metadata: { $jsonbContains: { tags: ['premium'] } } }` | JSONB/JSON |");
|
|
1405
|
+
lines.push("| `$jsonbContainedBy` | JSONB contained by | `{ metadata: { $jsonbContainedBy: {...} } }` | JSONB/JSON |");
|
|
1406
|
+
lines.push("| `$jsonbHasKey` | JSONB has key | `{ settings: { $jsonbHasKey: 'theme' } }` | JSONB/JSON |");
|
|
1407
|
+
lines.push("| `$jsonbHasAnyKeys` | JSONB has any keys | `{ settings: { $jsonbHasAnyKeys: ['dark', 'light'] } }` | JSONB/JSON |");
|
|
1408
|
+
lines.push("| `$jsonbHasAllKeys` | JSONB has all keys | `{ config: { $jsonbHasAllKeys: ['api', 'db'] } }` | JSONB/JSON |");
|
|
1409
|
+
lines.push("| `$jsonbPath` | JSONB nested value | `{ meta: { $jsonbPath: { path: ['user', 'age'], operator: '$gte', value: 18 } } }` | JSONB/JSON |");
|
|
1400
1410
|
lines.push("");
|
|
1401
1411
|
lines.push("### Logical Operators");
|
|
1402
1412
|
lines.push("");
|
|
@@ -1505,6 +1515,43 @@ function generateUnifiedContractMarkdown(contract) {
|
|
|
1505
1515
|
lines.push("");
|
|
1506
1516
|
lines.push("**Note:** Column names are validated by Zod schemas. Only valid table columns are accepted, preventing SQL injection.");
|
|
1507
1517
|
lines.push("");
|
|
1518
|
+
lines.push("## Vector Search");
|
|
1519
|
+
lines.push("");
|
|
1520
|
+
lines.push("For tables with `vector` columns (requires pgvector extension), use the `vector` parameter for similarity search:");
|
|
1521
|
+
lines.push("");
|
|
1522
|
+
lines.push("```typescript");
|
|
1523
|
+
lines.push("// Basic similarity search");
|
|
1524
|
+
lines.push("const results = await sdk.embeddings.list({");
|
|
1525
|
+
lines.push(" vector: {");
|
|
1526
|
+
lines.push(" field: 'embedding',");
|
|
1527
|
+
lines.push(" query: [0.1, 0.2, 0.3, ...], // Your embedding vector");
|
|
1528
|
+
lines.push(" metric: 'cosine' // 'cosine' (default), 'l2', or 'inner'");
|
|
1529
|
+
lines.push(" },");
|
|
1530
|
+
lines.push(" limit: 10");
|
|
1531
|
+
lines.push("});");
|
|
1532
|
+
lines.push("");
|
|
1533
|
+
lines.push("// Results include _distance field");
|
|
1534
|
+
lines.push("results.data[0]._distance; // Similarity distance");
|
|
1535
|
+
lines.push("");
|
|
1536
|
+
lines.push("// Distance threshold filtering");
|
|
1537
|
+
lines.push("const closeMatches = await sdk.embeddings.list({");
|
|
1538
|
+
lines.push(" vector: {");
|
|
1539
|
+
lines.push(" field: 'embedding',");
|
|
1540
|
+
lines.push(" query: queryVector,");
|
|
1541
|
+
lines.push(" maxDistance: 0.5 // Only return results within this distance");
|
|
1542
|
+
lines.push(" }");
|
|
1543
|
+
lines.push("});");
|
|
1544
|
+
lines.push("");
|
|
1545
|
+
lines.push("// Hybrid search: vector + WHERE filters");
|
|
1546
|
+
lines.push("const filtered = await sdk.embeddings.list({");
|
|
1547
|
+
lines.push(" vector: { field: 'embedding', query: queryVector },");
|
|
1548
|
+
lines.push(" where: {");
|
|
1549
|
+
lines.push(" status: 'published',");
|
|
1550
|
+
lines.push(" embedding: { $isNot: null }");
|
|
1551
|
+
lines.push(" }");
|
|
1552
|
+
lines.push("});");
|
|
1553
|
+
lines.push("```");
|
|
1554
|
+
lines.push("");
|
|
1508
1555
|
lines.push("## Resources");
|
|
1509
1556
|
lines.push("");
|
|
1510
1557
|
for (const resource of contract.resources) {
|
|
@@ -2534,7 +2581,8 @@ async function introspect(connectionString, schema) {
|
|
|
2534
2581
|
nullable: r.is_nullable === "YES",
|
|
2535
2582
|
hasDefault: r.column_default != null
|
|
2536
2583
|
};
|
|
2537
|
-
|
|
2584
|
+
const isVectorType = pgType === "vector" || pgType === "halfvec" || pgType === "sparsevec" || pgType === "bit";
|
|
2585
|
+
if (isVectorType && r.atttypmod != null && r.atttypmod !== -1) {
|
|
2538
2586
|
col.vectorDimension = r.atttypmod - 4;
|
|
2539
2587
|
}
|
|
2540
2588
|
t.columns.push(col);
|
|
@@ -3118,9 +3166,14 @@ ${hasAuth ? `
|
|
|
3118
3166
|
// src/emit-client.ts
|
|
3119
3167
|
init_utils();
|
|
3120
3168
|
init_emit_include_methods();
|
|
3169
|
+
function isVectorType(pgType) {
|
|
3170
|
+
const t = pgType.toLowerCase();
|
|
3171
|
+
return t === "vector" || t === "halfvec" || t === "sparsevec" || t === "bit";
|
|
3172
|
+
}
|
|
3121
3173
|
function emitClient(table, graph, opts, model) {
|
|
3122
3174
|
const Type = pascal(table.name);
|
|
3123
3175
|
const ext = opts.useJsExtensions ? ".js" : "";
|
|
3176
|
+
const hasVectorColumns = table.columns.some((c) => isVectorType(c.pgType));
|
|
3124
3177
|
const pkCols = Array.isArray(table.pk) ? table.pk : table.pk ? [table.pk] : [];
|
|
3125
3178
|
const safePk = pkCols.length ? pkCols : ["id"];
|
|
3126
3179
|
const hasCompositePk = safePk.length > 1;
|
|
@@ -3271,7 +3324,7 @@ export class ${Type}Client extends BaseClient {
|
|
|
3271
3324
|
where?: Where<Select${Type}>;
|
|
3272
3325
|
orderBy?: string | string[];
|
|
3273
3326
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3274
|
-
}): Promise<PaginatedResponse<Select${Type}
|
|
3327
|
+
}): Promise<PaginatedResponse<Select${Type}>>;${hasVectorColumns ? `
|
|
3275
3328
|
/**
|
|
3276
3329
|
* List ${table.name} records with vector similarity search
|
|
3277
3330
|
* @param params - Query parameters with vector search enabled
|
|
@@ -3291,7 +3344,7 @@ export class ${Type}Client extends BaseClient {
|
|
|
3291
3344
|
};
|
|
3292
3345
|
orderBy?: string | string[];
|
|
3293
3346
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3294
|
-
}): Promise<PaginatedResponse<Select${Type} & { _distance: number }
|
|
3347
|
+
}): Promise<PaginatedResponse<Select${Type} & { _distance: number }>>;` : ""}
|
|
3295
3348
|
/**
|
|
3296
3349
|
* List ${table.name} records with pagination and filtering, with JSONB type overrides
|
|
3297
3350
|
* @param params - Query parameters with typed JSONB fields in where clause
|
|
@@ -3301,13 +3354,13 @@ export class ${Type}Client extends BaseClient {
|
|
|
3301
3354
|
include?: any;
|
|
3302
3355
|
limit?: number;
|
|
3303
3356
|
offset?: number;
|
|
3304
|
-
where?: Where<MergeJsonb<Select${Type}, TJsonb
|
|
3357
|
+
where?: Where<MergeJsonb<Select${Type}, TJsonb>>;${hasVectorColumns ? `
|
|
3305
3358
|
vector?: {
|
|
3306
3359
|
field: string;
|
|
3307
3360
|
query: number[];
|
|
3308
3361
|
metric?: "cosine" | "l2" | "inner";
|
|
3309
3362
|
maxDistance?: number;
|
|
3310
|
-
}
|
|
3363
|
+
};` : ""}
|
|
3311
3364
|
orderBy?: string | string[];
|
|
3312
3365
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3313
3366
|
}): Promise<PaginatedResponse<MergeJsonb<Select${Type}, TJsonb>>>;
|
package/dist/index.js
CHANGED
|
@@ -1050,6 +1050,8 @@ function postgresTypeToTsType(column, enums) {
|
|
|
1050
1050
|
case "_int8":
|
|
1051
1051
|
case "_integer":
|
|
1052
1052
|
return "number[]";
|
|
1053
|
+
case "vector":
|
|
1054
|
+
return "number[]";
|
|
1053
1055
|
default:
|
|
1054
1056
|
return "string";
|
|
1055
1057
|
}
|
|
@@ -1203,6 +1205,8 @@ function postgresTypeToJsonType(pgType, enums) {
|
|
|
1203
1205
|
case "_int8":
|
|
1204
1206
|
case "_integer":
|
|
1205
1207
|
return "number[]";
|
|
1208
|
+
case "vector":
|
|
1209
|
+
return "number[]";
|
|
1206
1210
|
default:
|
|
1207
1211
|
return "string";
|
|
1208
1212
|
}
|
|
@@ -1396,6 +1400,12 @@ function generateUnifiedContractMarkdown(contract) {
|
|
|
1396
1400
|
lines.push("| `$ilike` | Pattern match (case-insensitive) | `{ email: { $ilike: '%@GMAIL%' } }` | String |");
|
|
1397
1401
|
lines.push("| `$is` | IS NULL | `{ deleted_at: { $is: null } }` | Nullable fields |");
|
|
1398
1402
|
lines.push("| `$isNot` | IS NOT NULL | `{ created_by: { $isNot: null } }` | Nullable fields |");
|
|
1403
|
+
lines.push("| `$jsonbContains` | JSONB contains | `{ metadata: { $jsonbContains: { tags: ['premium'] } } }` | JSONB/JSON |");
|
|
1404
|
+
lines.push("| `$jsonbContainedBy` | JSONB contained by | `{ metadata: { $jsonbContainedBy: {...} } }` | JSONB/JSON |");
|
|
1405
|
+
lines.push("| `$jsonbHasKey` | JSONB has key | `{ settings: { $jsonbHasKey: 'theme' } }` | JSONB/JSON |");
|
|
1406
|
+
lines.push("| `$jsonbHasAnyKeys` | JSONB has any keys | `{ settings: { $jsonbHasAnyKeys: ['dark', 'light'] } }` | JSONB/JSON |");
|
|
1407
|
+
lines.push("| `$jsonbHasAllKeys` | JSONB has all keys | `{ config: { $jsonbHasAllKeys: ['api', 'db'] } }` | JSONB/JSON |");
|
|
1408
|
+
lines.push("| `$jsonbPath` | JSONB nested value | `{ meta: { $jsonbPath: { path: ['user', 'age'], operator: '$gte', value: 18 } } }` | JSONB/JSON |");
|
|
1399
1409
|
lines.push("");
|
|
1400
1410
|
lines.push("### Logical Operators");
|
|
1401
1411
|
lines.push("");
|
|
@@ -1504,6 +1514,43 @@ function generateUnifiedContractMarkdown(contract) {
|
|
|
1504
1514
|
lines.push("");
|
|
1505
1515
|
lines.push("**Note:** Column names are validated by Zod schemas. Only valid table columns are accepted, preventing SQL injection.");
|
|
1506
1516
|
lines.push("");
|
|
1517
|
+
lines.push("## Vector Search");
|
|
1518
|
+
lines.push("");
|
|
1519
|
+
lines.push("For tables with `vector` columns (requires pgvector extension), use the `vector` parameter for similarity search:");
|
|
1520
|
+
lines.push("");
|
|
1521
|
+
lines.push("```typescript");
|
|
1522
|
+
lines.push("// Basic similarity search");
|
|
1523
|
+
lines.push("const results = await sdk.embeddings.list({");
|
|
1524
|
+
lines.push(" vector: {");
|
|
1525
|
+
lines.push(" field: 'embedding',");
|
|
1526
|
+
lines.push(" query: [0.1, 0.2, 0.3, ...], // Your embedding vector");
|
|
1527
|
+
lines.push(" metric: 'cosine' // 'cosine' (default), 'l2', or 'inner'");
|
|
1528
|
+
lines.push(" },");
|
|
1529
|
+
lines.push(" limit: 10");
|
|
1530
|
+
lines.push("});");
|
|
1531
|
+
lines.push("");
|
|
1532
|
+
lines.push("// Results include _distance field");
|
|
1533
|
+
lines.push("results.data[0]._distance; // Similarity distance");
|
|
1534
|
+
lines.push("");
|
|
1535
|
+
lines.push("// Distance threshold filtering");
|
|
1536
|
+
lines.push("const closeMatches = await sdk.embeddings.list({");
|
|
1537
|
+
lines.push(" vector: {");
|
|
1538
|
+
lines.push(" field: 'embedding',");
|
|
1539
|
+
lines.push(" query: queryVector,");
|
|
1540
|
+
lines.push(" maxDistance: 0.5 // Only return results within this distance");
|
|
1541
|
+
lines.push(" }");
|
|
1542
|
+
lines.push("});");
|
|
1543
|
+
lines.push("");
|
|
1544
|
+
lines.push("// Hybrid search: vector + WHERE filters");
|
|
1545
|
+
lines.push("const filtered = await sdk.embeddings.list({");
|
|
1546
|
+
lines.push(" vector: { field: 'embedding', query: queryVector },");
|
|
1547
|
+
lines.push(" where: {");
|
|
1548
|
+
lines.push(" status: 'published',");
|
|
1549
|
+
lines.push(" embedding: { $isNot: null }");
|
|
1550
|
+
lines.push(" }");
|
|
1551
|
+
lines.push("});");
|
|
1552
|
+
lines.push("```");
|
|
1553
|
+
lines.push("");
|
|
1507
1554
|
lines.push("## Resources");
|
|
1508
1555
|
lines.push("");
|
|
1509
1556
|
for (const resource of contract.resources) {
|
|
@@ -1705,7 +1752,8 @@ async function introspect(connectionString, schema) {
|
|
|
1705
1752
|
nullable: r.is_nullable === "YES",
|
|
1706
1753
|
hasDefault: r.column_default != null
|
|
1707
1754
|
};
|
|
1708
|
-
|
|
1755
|
+
const isVectorType = pgType === "vector" || pgType === "halfvec" || pgType === "sparsevec" || pgType === "bit";
|
|
1756
|
+
if (isVectorType && r.atttypmod != null && r.atttypmod !== -1) {
|
|
1709
1757
|
col.vectorDimension = r.atttypmod - 4;
|
|
1710
1758
|
}
|
|
1711
1759
|
t.columns.push(col);
|
|
@@ -2289,9 +2337,14 @@ ${hasAuth ? `
|
|
|
2289
2337
|
// src/emit-client.ts
|
|
2290
2338
|
init_utils();
|
|
2291
2339
|
init_emit_include_methods();
|
|
2340
|
+
function isVectorType(pgType) {
|
|
2341
|
+
const t = pgType.toLowerCase();
|
|
2342
|
+
return t === "vector" || t === "halfvec" || t === "sparsevec" || t === "bit";
|
|
2343
|
+
}
|
|
2292
2344
|
function emitClient(table, graph, opts, model) {
|
|
2293
2345
|
const Type = pascal(table.name);
|
|
2294
2346
|
const ext = opts.useJsExtensions ? ".js" : "";
|
|
2347
|
+
const hasVectorColumns = table.columns.some((c) => isVectorType(c.pgType));
|
|
2295
2348
|
const pkCols = Array.isArray(table.pk) ? table.pk : table.pk ? [table.pk] : [];
|
|
2296
2349
|
const safePk = pkCols.length ? pkCols : ["id"];
|
|
2297
2350
|
const hasCompositePk = safePk.length > 1;
|
|
@@ -2442,7 +2495,7 @@ export class ${Type}Client extends BaseClient {
|
|
|
2442
2495
|
where?: Where<Select${Type}>;
|
|
2443
2496
|
orderBy?: string | string[];
|
|
2444
2497
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2445
|
-
}): Promise<PaginatedResponse<Select${Type}
|
|
2498
|
+
}): Promise<PaginatedResponse<Select${Type}>>;${hasVectorColumns ? `
|
|
2446
2499
|
/**
|
|
2447
2500
|
* List ${table.name} records with vector similarity search
|
|
2448
2501
|
* @param params - Query parameters with vector search enabled
|
|
@@ -2462,7 +2515,7 @@ export class ${Type}Client extends BaseClient {
|
|
|
2462
2515
|
};
|
|
2463
2516
|
orderBy?: string | string[];
|
|
2464
2517
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2465
|
-
}): Promise<PaginatedResponse<Select${Type} & { _distance: number }
|
|
2518
|
+
}): Promise<PaginatedResponse<Select${Type} & { _distance: number }>>;` : ""}
|
|
2466
2519
|
/**
|
|
2467
2520
|
* List ${table.name} records with pagination and filtering, with JSONB type overrides
|
|
2468
2521
|
* @param params - Query parameters with typed JSONB fields in where clause
|
|
@@ -2472,13 +2525,13 @@ export class ${Type}Client extends BaseClient {
|
|
|
2472
2525
|
include?: any;
|
|
2473
2526
|
limit?: number;
|
|
2474
2527
|
offset?: number;
|
|
2475
|
-
where?: Where<MergeJsonb<Select${Type}, TJsonb
|
|
2528
|
+
where?: Where<MergeJsonb<Select${Type}, TJsonb>>;${hasVectorColumns ? `
|
|
2476
2529
|
vector?: {
|
|
2477
2530
|
field: string;
|
|
2478
2531
|
query: number[];
|
|
2479
2532
|
metric?: "cosine" | "l2" | "inner";
|
|
2480
2533
|
maxDistance?: number;
|
|
2481
|
-
}
|
|
2534
|
+
};` : ""}
|
|
2482
2535
|
orderBy?: string | string[];
|
|
2483
2536
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2484
2537
|
}): Promise<PaginatedResponse<MergeJsonb<Select${Type}, TJsonb>>>;
|