postgresdk 0.16.2 → 0.16.4
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 +148 -86
- package/dist/index.js +148 -86
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1035,7 +1035,7 @@ function postgresTypeToTsType(column, enums) {
|
|
|
1035
1035
|
return "string";
|
|
1036
1036
|
case "json":
|
|
1037
1037
|
case "jsonb":
|
|
1038
|
-
return "
|
|
1038
|
+
return "JsonValue";
|
|
1039
1039
|
case "uuid":
|
|
1040
1040
|
return "string";
|
|
1041
1041
|
case "text[]":
|
|
@@ -3175,10 +3175,15 @@ function isVectorType2(pgType) {
|
|
|
3175
3175
|
const t = pgType.toLowerCase();
|
|
3176
3176
|
return t === "vector" || t === "halfvec" || t === "sparsevec" || t === "bit";
|
|
3177
3177
|
}
|
|
3178
|
+
function isJsonbType(pgType) {
|
|
3179
|
+
const t = pgType.toLowerCase();
|
|
3180
|
+
return t === "json" || t === "jsonb";
|
|
3181
|
+
}
|
|
3178
3182
|
function emitClient(table, graph, opts, model) {
|
|
3179
3183
|
const Type = pascal(table.name);
|
|
3180
3184
|
const ext = opts.useJsExtensions ? ".js" : "";
|
|
3181
3185
|
const hasVectorColumns = table.columns.some((c) => isVectorType2(c.pgType));
|
|
3186
|
+
const hasJsonbColumns = table.columns.some((c) => isJsonbType(c.pgType));
|
|
3182
3187
|
if (process.env.SDK_DEBUG) {
|
|
3183
3188
|
const vectorCols = table.columns.filter((c) => isVectorType2(c.pgType));
|
|
3184
3189
|
if (vectorCols.length > 0) {
|
|
@@ -3264,60 +3269,58 @@ ${typeImports}
|
|
|
3264
3269
|
${otherTableImports.join(`
|
|
3265
3270
|
`)}
|
|
3266
3271
|
|
|
3267
|
-
/**
|
|
3268
|
-
* Helper type to merge JSONB type overrides into base types
|
|
3269
|
-
* @example
|
|
3270
|
-
* type UserWithMetadata = MergeJsonb<SelectUser, { metadata: { tags: string[] } }>;
|
|
3271
|
-
*/
|
|
3272
|
-
type MergeJsonb<TBase, TJsonb> = Omit<TBase, keyof TJsonb> & TJsonb;
|
|
3273
|
-
|
|
3274
3272
|
/**
|
|
3275
3273
|
* Client for ${table.name} table operations
|
|
3276
3274
|
*/
|
|
3277
3275
|
export class ${Type}Client extends BaseClient {
|
|
3278
3276
|
private readonly resource = "/v1/${table.name}";
|
|
3279
3277
|
|
|
3280
|
-
/**
|
|
3278
|
+
${hasJsonbColumns ? ` /**
|
|
3281
3279
|
* Create a new ${table.name} record
|
|
3282
3280
|
* @param data - The data to insert
|
|
3283
3281
|
* @returns The created record
|
|
3284
|
-
*/
|
|
3285
|
-
async create(data: Insert${Type}): Promise<Select${Type}>;
|
|
3286
|
-
/**
|
|
3287
|
-
* Create a new ${table.name} record with JSONB type overrides
|
|
3288
|
-
* @param data - The data to insert
|
|
3289
|
-
* @returns The created record with typed JSONB fields
|
|
3290
3282
|
* @example
|
|
3283
|
+
* // With JSONB type override:
|
|
3291
3284
|
* type Metadata = { tags: string[]; prefs: { theme: 'light' | 'dark' } };
|
|
3292
3285
|
* const user = await client.create<{ metadata: Metadata }>({ name: 'Alice', metadata: { tags: [], prefs: { theme: 'light' } } });
|
|
3293
3286
|
*/
|
|
3294
|
-
async create<TJsonb extends Partial<Select${Type}
|
|
3295
|
-
data:
|
|
3296
|
-
): Promise<
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3287
|
+
async create<TJsonb extends Partial<Select${Type}> = {}>(
|
|
3288
|
+
data: Insert${Type}<TJsonb>
|
|
3289
|
+
): Promise<Select${Type}<TJsonb>> {
|
|
3290
|
+
return this.post<Select${Type}<TJsonb>>(this.resource, data);
|
|
3291
|
+
}` : ` /**
|
|
3292
|
+
* Create a new ${table.name} record
|
|
3293
|
+
* @param data - The data to insert
|
|
3294
|
+
* @returns The created record
|
|
3295
|
+
*/
|
|
3296
|
+
async create(data: Insert${Type}): Promise<Select${Type}> {
|
|
3297
|
+
return this.post<Select${Type}>(this.resource, data);
|
|
3298
|
+
}`}
|
|
3300
3299
|
|
|
3301
|
-
/**
|
|
3300
|
+
${hasJsonbColumns ? ` /**
|
|
3302
3301
|
* Get a ${table.name} record by primary key
|
|
3303
3302
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3304
3303
|
* @returns The record if found, null otherwise
|
|
3304
|
+
* @example
|
|
3305
|
+
* // With JSONB type override:
|
|
3306
|
+
* const user = await client.getByPk<{ metadata: Metadata }>('user-id');
|
|
3305
3307
|
*/
|
|
3306
|
-
async getByPk
|
|
3307
|
-
|
|
3308
|
-
|
|
3308
|
+
async getByPk<TJsonb extends Partial<Select${Type}> = {}>(
|
|
3309
|
+
pk: ${pkType}
|
|
3310
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
3311
|
+
const path = ${pkPathExpr};
|
|
3312
|
+
return this.get<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`);
|
|
3313
|
+
}` : ` /**
|
|
3314
|
+
* Get a ${table.name} record by primary key
|
|
3309
3315
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3310
|
-
* @returns The record
|
|
3316
|
+
* @returns The record if found, null otherwise
|
|
3311
3317
|
*/
|
|
3312
|
-
async getByPk
|
|
3313
|
-
pk: ${pkType}
|
|
3314
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
3315
|
-
async getByPk(pk: ${pkType}): Promise<any> {
|
|
3318
|
+
async getByPk(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
3316
3319
|
const path = ${pkPathExpr};
|
|
3317
|
-
return this.get<
|
|
3318
|
-
}
|
|
3320
|
+
return this.get<Select${Type} | null>(\`\${this.resource}/\${path}\`);
|
|
3321
|
+
}`}
|
|
3319
3322
|
|
|
3320
|
-
/**
|
|
3323
|
+
${hasJsonbColumns ? ` /**
|
|
3321
3324
|
* List ${table.name} records with pagination and filtering
|
|
3322
3325
|
* @param params - Query parameters
|
|
3323
3326
|
* @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
|
|
@@ -3327,45 +3330,41 @@ export class ${Type}Client extends BaseClient {
|
|
|
3327
3330
|
* @param params.offset - Number of records to skip for pagination
|
|
3328
3331
|
* @param params.include - Related records to include (see listWith* methods for typed includes)
|
|
3329
3332
|
* @returns Paginated results with data, total count, and hasMore flag
|
|
3333
|
+
* @example
|
|
3334
|
+
* // With JSONB type override:
|
|
3335
|
+
* const users = await client.list<{ metadata: Metadata }>({ where: { status: 'active' } });
|
|
3330
3336
|
*/
|
|
3331
|
-
async list(params?: {
|
|
3332
|
-
include?: any;
|
|
3333
|
-
limit?: number;
|
|
3334
|
-
offset?: number;
|
|
3335
|
-
where?: Where<Select${Type}>;
|
|
3336
|
-
orderBy?: string | string[];
|
|
3337
|
-
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3338
|
-
}): Promise<PaginatedResponse<Select${Type}>>;${hasVectorColumns ? `
|
|
3339
|
-
/**
|
|
3340
|
-
* List ${table.name} records with vector similarity search
|
|
3341
|
-
* @param params - Query parameters with vector search enabled
|
|
3342
|
-
* @param params.vector - Vector similarity search configuration
|
|
3343
|
-
* @returns Paginated results with _distance field included
|
|
3344
|
-
*/
|
|
3345
|
-
async list(params: {
|
|
3337
|
+
async list<TJsonb extends Partial<Select${Type}> = {}>(params?: {
|
|
3346
3338
|
include?: any;
|
|
3347
3339
|
limit?: number;
|
|
3348
3340
|
offset?: number;
|
|
3349
|
-
where?: Where<Select${Type}
|
|
3350
|
-
vector
|
|
3341
|
+
where?: Where<Select${Type}<TJsonb>>;${hasVectorColumns ? `
|
|
3342
|
+
vector?: {
|
|
3351
3343
|
field: string;
|
|
3352
3344
|
query: number[];
|
|
3353
3345
|
metric?: "cosine" | "l2" | "inner";
|
|
3354
3346
|
maxDistance?: number;
|
|
3355
|
-
}
|
|
3347
|
+
};` : ""}
|
|
3356
3348
|
orderBy?: string | string[];
|
|
3357
3349
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3358
|
-
}): Promise<PaginatedResponse<Select${Type} & { _distance
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
*
|
|
3362
|
-
* @
|
|
3350
|
+
}): Promise<PaginatedResponse<Select${Type}<TJsonb>${hasVectorColumns ? " & { _distance?: number }" : ""}>> {
|
|
3351
|
+
return this.post<PaginatedResponse<Select${Type}<TJsonb>${hasVectorColumns ? " & { _distance?: number }" : ""}>>(\`\${this.resource}/list\`, params ?? {});
|
|
3352
|
+
}` : ` /**
|
|
3353
|
+
* List ${table.name} records with pagination and filtering
|
|
3354
|
+
* @param params - Query parameters
|
|
3355
|
+
* @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
|
|
3356
|
+
* @param params.orderBy - Column(s) to sort by
|
|
3357
|
+
* @param params.order - Sort direction(s): "asc" or "desc"
|
|
3358
|
+
* @param params.limit - Maximum number of records to return (default: 50, max: 100)
|
|
3359
|
+
* @param params.offset - Number of records to skip for pagination
|
|
3360
|
+
* @param params.include - Related records to include (see listWith* methods for typed includes)
|
|
3361
|
+
* @returns Paginated results with data, total count, and hasMore flag
|
|
3363
3362
|
*/
|
|
3364
|
-
async list
|
|
3363
|
+
async list(params?: {
|
|
3365
3364
|
include?: any;
|
|
3366
3365
|
limit?: number;
|
|
3367
3366
|
offset?: number;
|
|
3368
|
-
where?: Where<
|
|
3367
|
+
where?: Where<Select${Type}>;${hasVectorColumns ? `
|
|
3369
3368
|
vector?: {
|
|
3370
3369
|
field: string;
|
|
3371
3370
|
query: number[];
|
|
@@ -3374,51 +3373,58 @@ export class ${Type}Client extends BaseClient {
|
|
|
3374
3373
|
};` : ""}
|
|
3375
3374
|
orderBy?: string | string[];
|
|
3376
3375
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
3377
|
-
}): Promise<PaginatedResponse<
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
}
|
|
3376
|
+
}): Promise<PaginatedResponse<Select${Type}${hasVectorColumns ? " & { _distance?: number }" : ""}>> {
|
|
3377
|
+
return this.post<PaginatedResponse<Select${Type}${hasVectorColumns ? " & { _distance?: number }" : ""}>>(\`\${this.resource}/list\`, params ?? {});
|
|
3378
|
+
}`}
|
|
3381
3379
|
|
|
3382
|
-
/**
|
|
3380
|
+
${hasJsonbColumns ? ` /**
|
|
3383
3381
|
* Update a ${table.name} record by primary key
|
|
3384
3382
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3385
3383
|
* @param patch - Partial data to update
|
|
3386
3384
|
* @returns The updated record if found, null otherwise
|
|
3385
|
+
* @example
|
|
3386
|
+
* // With JSONB type override:
|
|
3387
|
+
* const user = await client.update<{ metadata: Metadata }>('user-id', { metadata: { tags: ['new'] } });
|
|
3387
3388
|
*/
|
|
3388
|
-
async update
|
|
3389
|
-
|
|
3390
|
-
|
|
3389
|
+
async update<TJsonb extends Partial<Select${Type}> = {}>(
|
|
3390
|
+
pk: ${pkType},
|
|
3391
|
+
patch: Update${Type}<TJsonb>
|
|
3392
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
3393
|
+
const path = ${pkPathExpr};
|
|
3394
|
+
return this.patch<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`, patch);
|
|
3395
|
+
}` : ` /**
|
|
3396
|
+
* Update a ${table.name} record by primary key
|
|
3391
3397
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3392
|
-
* @param patch - Partial data to update
|
|
3393
|
-
* @returns The updated record
|
|
3398
|
+
* @param patch - Partial data to update
|
|
3399
|
+
* @returns The updated record if found, null otherwise
|
|
3394
3400
|
*/
|
|
3395
|
-
async update
|
|
3396
|
-
pk: ${pkType},
|
|
3397
|
-
patch: MergeJsonb<Update${Type}, TJsonb>
|
|
3398
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
3399
|
-
async update(pk: ${pkType}, patch: any): Promise<any> {
|
|
3401
|
+
async update(pk: ${pkType}, patch: Update${Type}): Promise<Select${Type} | null> {
|
|
3400
3402
|
const path = ${pkPathExpr};
|
|
3401
|
-
return this.patch<
|
|
3402
|
-
}
|
|
3403
|
+
return this.patch<Select${Type} | null>(\`\${this.resource}/\${path}\`, patch);
|
|
3404
|
+
}`}
|
|
3403
3405
|
|
|
3404
|
-
/**
|
|
3406
|
+
${hasJsonbColumns ? ` /**
|
|
3405
3407
|
* Delete a ${table.name} record by primary key
|
|
3406
3408
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3407
3409
|
* @returns The deleted record if found, null otherwise
|
|
3410
|
+
* @example
|
|
3411
|
+
* // With JSONB type override:
|
|
3412
|
+
* const user = await client.delete<{ metadata: Metadata }>('user-id');
|
|
3408
3413
|
*/
|
|
3409
|
-
async delete
|
|
3410
|
-
|
|
3411
|
-
|
|
3414
|
+
async delete<TJsonb extends Partial<Select${Type}> = {}>(
|
|
3415
|
+
pk: ${pkType}
|
|
3416
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
3417
|
+
const path = ${pkPathExpr};
|
|
3418
|
+
return this.del<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`);
|
|
3419
|
+
}` : ` /**
|
|
3420
|
+
* Delete a ${table.name} record by primary key
|
|
3412
3421
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
3413
|
-
* @returns The deleted record
|
|
3422
|
+
* @returns The deleted record if found, null otherwise
|
|
3414
3423
|
*/
|
|
3415
|
-
async delete
|
|
3416
|
-
pk: ${pkType}
|
|
3417
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
3418
|
-
async delete(pk: ${pkType}): Promise<any> {
|
|
3424
|
+
async delete(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
3419
3425
|
const path = ${pkPathExpr};
|
|
3420
|
-
return this.del<
|
|
3421
|
-
}
|
|
3426
|
+
return this.del<Select${Type} | null>(\`\${this.resource}/\${path}\`);
|
|
3427
|
+
}`}
|
|
3422
3428
|
${includeMethodsCode}}
|
|
3423
3429
|
`;
|
|
3424
3430
|
}
|
|
@@ -3986,9 +3992,14 @@ function tsTypeFor(pgType, opts, enums) {
|
|
|
3986
3992
|
return "unknown";
|
|
3987
3993
|
return "string";
|
|
3988
3994
|
}
|
|
3995
|
+
function isJsonbType2(pgType) {
|
|
3996
|
+
const t = pgType.toLowerCase();
|
|
3997
|
+
return t === "json" || t === "jsonb";
|
|
3998
|
+
}
|
|
3989
3999
|
var pascal2 = (s) => s.split(/[_\s-]+/).map((w) => w?.[0] ? w[0].toUpperCase() + w.slice(1) : "").join("");
|
|
3990
4000
|
function emitTypes(table, opts, enums) {
|
|
3991
4001
|
const Type = pascal2(table.name);
|
|
4002
|
+
const hasJsonbColumns = table.columns.some((col) => isJsonbType2(col.pgType));
|
|
3992
4003
|
const insertFields = table.columns.map((col) => {
|
|
3993
4004
|
const base = tsTypeFor(col.pgType, opts, enums);
|
|
3994
4005
|
const optional = col.hasDefault || col.nullable ? "?" : "";
|
|
@@ -4002,6 +4013,57 @@ function emitTypes(table, opts, enums) {
|
|
|
4002
4013
|
return ` ${col.name}: ${valueType};`;
|
|
4003
4014
|
}).join(`
|
|
4004
4015
|
`);
|
|
4016
|
+
const baseInsertType = `type _Insert${Type}Base = {
|
|
4017
|
+
${insertFields}
|
|
4018
|
+
};`;
|
|
4019
|
+
const baseSelectType = `type _Select${Type}Base = {
|
|
4020
|
+
${selectFields}
|
|
4021
|
+
};`;
|
|
4022
|
+
if (hasJsonbColumns) {
|
|
4023
|
+
return `/**
|
|
4024
|
+
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
4025
|
+
*
|
|
4026
|
+
* This file was automatically generated by PostgreSDK.
|
|
4027
|
+
* Any manual changes will be overwritten on the next generation.
|
|
4028
|
+
*
|
|
4029
|
+
* To make changes, modify your schema or configuration and regenerate.
|
|
4030
|
+
*/
|
|
4031
|
+
|
|
4032
|
+
${baseInsertType}
|
|
4033
|
+
|
|
4034
|
+
${baseSelectType}
|
|
4035
|
+
|
|
4036
|
+
/**
|
|
4037
|
+
* Type for inserting a new ${table.name} record.
|
|
4038
|
+
* Fields with defaults or nullable columns are optional.
|
|
4039
|
+
*
|
|
4040
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
4041
|
+
* @example Insert${Type}<{ metadata: MyMetadataType }>
|
|
4042
|
+
*/
|
|
4043
|
+
export type Insert${Type}<TJsonb extends Partial<_Insert${Type}Base> = {}> =
|
|
4044
|
+
Omit<_Insert${Type}Base, keyof TJsonb> & TJsonb;
|
|
4045
|
+
|
|
4046
|
+
/**
|
|
4047
|
+
* Type for updating an existing ${table.name} record.
|
|
4048
|
+
* All fields are optional, allowing partial updates.
|
|
4049
|
+
*
|
|
4050
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
4051
|
+
* @example Update${Type}<{ metadata: MyMetadataType }>
|
|
4052
|
+
*/
|
|
4053
|
+
export type Update${Type}<TJsonb extends Partial<_Select${Type}Base> = {}> =
|
|
4054
|
+
Partial<Omit<_Insert${Type}Base, keyof TJsonb> & TJsonb>;
|
|
4055
|
+
|
|
4056
|
+
/**
|
|
4057
|
+
* Type representing a ${table.name} record from the database.
|
|
4058
|
+
* All fields are included as returned by SELECT queries.
|
|
4059
|
+
*
|
|
4060
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
4061
|
+
* @example Select${Type}<{ metadata: MyMetadataType }>
|
|
4062
|
+
*/
|
|
4063
|
+
export type Select${Type}<TJsonb extends Partial<_Select${Type}Base> = {}> =
|
|
4064
|
+
Omit<_Select${Type}Base, keyof TJsonb> & TJsonb;
|
|
4065
|
+
`;
|
|
4066
|
+
}
|
|
4005
4067
|
return `/**
|
|
4006
4068
|
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
4007
4069
|
*
|
package/dist/index.js
CHANGED
|
@@ -1034,7 +1034,7 @@ function postgresTypeToTsType(column, enums) {
|
|
|
1034
1034
|
return "string";
|
|
1035
1035
|
case "json":
|
|
1036
1036
|
case "jsonb":
|
|
1037
|
-
return "
|
|
1037
|
+
return "JsonValue";
|
|
1038
1038
|
case "uuid":
|
|
1039
1039
|
return "string";
|
|
1040
1040
|
case "text[]":
|
|
@@ -2346,10 +2346,15 @@ function isVectorType2(pgType) {
|
|
|
2346
2346
|
const t = pgType.toLowerCase();
|
|
2347
2347
|
return t === "vector" || t === "halfvec" || t === "sparsevec" || t === "bit";
|
|
2348
2348
|
}
|
|
2349
|
+
function isJsonbType(pgType) {
|
|
2350
|
+
const t = pgType.toLowerCase();
|
|
2351
|
+
return t === "json" || t === "jsonb";
|
|
2352
|
+
}
|
|
2349
2353
|
function emitClient(table, graph, opts, model) {
|
|
2350
2354
|
const Type = pascal(table.name);
|
|
2351
2355
|
const ext = opts.useJsExtensions ? ".js" : "";
|
|
2352
2356
|
const hasVectorColumns = table.columns.some((c) => isVectorType2(c.pgType));
|
|
2357
|
+
const hasJsonbColumns = table.columns.some((c) => isJsonbType(c.pgType));
|
|
2353
2358
|
if (process.env.SDK_DEBUG) {
|
|
2354
2359
|
const vectorCols = table.columns.filter((c) => isVectorType2(c.pgType));
|
|
2355
2360
|
if (vectorCols.length > 0) {
|
|
@@ -2435,60 +2440,58 @@ ${typeImports}
|
|
|
2435
2440
|
${otherTableImports.join(`
|
|
2436
2441
|
`)}
|
|
2437
2442
|
|
|
2438
|
-
/**
|
|
2439
|
-
* Helper type to merge JSONB type overrides into base types
|
|
2440
|
-
* @example
|
|
2441
|
-
* type UserWithMetadata = MergeJsonb<SelectUser, { metadata: { tags: string[] } }>;
|
|
2442
|
-
*/
|
|
2443
|
-
type MergeJsonb<TBase, TJsonb> = Omit<TBase, keyof TJsonb> & TJsonb;
|
|
2444
|
-
|
|
2445
2443
|
/**
|
|
2446
2444
|
* Client for ${table.name} table operations
|
|
2447
2445
|
*/
|
|
2448
2446
|
export class ${Type}Client extends BaseClient {
|
|
2449
2447
|
private readonly resource = "/v1/${table.name}";
|
|
2450
2448
|
|
|
2451
|
-
/**
|
|
2449
|
+
${hasJsonbColumns ? ` /**
|
|
2452
2450
|
* Create a new ${table.name} record
|
|
2453
2451
|
* @param data - The data to insert
|
|
2454
2452
|
* @returns The created record
|
|
2455
|
-
*/
|
|
2456
|
-
async create(data: Insert${Type}): Promise<Select${Type}>;
|
|
2457
|
-
/**
|
|
2458
|
-
* Create a new ${table.name} record with JSONB type overrides
|
|
2459
|
-
* @param data - The data to insert
|
|
2460
|
-
* @returns The created record with typed JSONB fields
|
|
2461
2453
|
* @example
|
|
2454
|
+
* // With JSONB type override:
|
|
2462
2455
|
* type Metadata = { tags: string[]; prefs: { theme: 'light' | 'dark' } };
|
|
2463
2456
|
* const user = await client.create<{ metadata: Metadata }>({ name: 'Alice', metadata: { tags: [], prefs: { theme: 'light' } } });
|
|
2464
2457
|
*/
|
|
2465
|
-
async create<TJsonb extends Partial<Select${Type}
|
|
2466
|
-
data:
|
|
2467
|
-
): Promise<
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2458
|
+
async create<TJsonb extends Partial<Select${Type}> = {}>(
|
|
2459
|
+
data: Insert${Type}<TJsonb>
|
|
2460
|
+
): Promise<Select${Type}<TJsonb>> {
|
|
2461
|
+
return this.post<Select${Type}<TJsonb>>(this.resource, data);
|
|
2462
|
+
}` : ` /**
|
|
2463
|
+
* Create a new ${table.name} record
|
|
2464
|
+
* @param data - The data to insert
|
|
2465
|
+
* @returns The created record
|
|
2466
|
+
*/
|
|
2467
|
+
async create(data: Insert${Type}): Promise<Select${Type}> {
|
|
2468
|
+
return this.post<Select${Type}>(this.resource, data);
|
|
2469
|
+
}`}
|
|
2471
2470
|
|
|
2472
|
-
/**
|
|
2471
|
+
${hasJsonbColumns ? ` /**
|
|
2473
2472
|
* Get a ${table.name} record by primary key
|
|
2474
2473
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2475
2474
|
* @returns The record if found, null otherwise
|
|
2475
|
+
* @example
|
|
2476
|
+
* // With JSONB type override:
|
|
2477
|
+
* const user = await client.getByPk<{ metadata: Metadata }>('user-id');
|
|
2476
2478
|
*/
|
|
2477
|
-
async getByPk
|
|
2478
|
-
|
|
2479
|
-
|
|
2479
|
+
async getByPk<TJsonb extends Partial<Select${Type}> = {}>(
|
|
2480
|
+
pk: ${pkType}
|
|
2481
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
2482
|
+
const path = ${pkPathExpr};
|
|
2483
|
+
return this.get<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`);
|
|
2484
|
+
}` : ` /**
|
|
2485
|
+
* Get a ${table.name} record by primary key
|
|
2480
2486
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2481
|
-
* @returns The record
|
|
2487
|
+
* @returns The record if found, null otherwise
|
|
2482
2488
|
*/
|
|
2483
|
-
async getByPk
|
|
2484
|
-
pk: ${pkType}
|
|
2485
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
2486
|
-
async getByPk(pk: ${pkType}): Promise<any> {
|
|
2489
|
+
async getByPk(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
2487
2490
|
const path = ${pkPathExpr};
|
|
2488
|
-
return this.get<
|
|
2489
|
-
}
|
|
2491
|
+
return this.get<Select${Type} | null>(\`\${this.resource}/\${path}\`);
|
|
2492
|
+
}`}
|
|
2490
2493
|
|
|
2491
|
-
/**
|
|
2494
|
+
${hasJsonbColumns ? ` /**
|
|
2492
2495
|
* List ${table.name} records with pagination and filtering
|
|
2493
2496
|
* @param params - Query parameters
|
|
2494
2497
|
* @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
|
|
@@ -2498,45 +2501,41 @@ export class ${Type}Client extends BaseClient {
|
|
|
2498
2501
|
* @param params.offset - Number of records to skip for pagination
|
|
2499
2502
|
* @param params.include - Related records to include (see listWith* methods for typed includes)
|
|
2500
2503
|
* @returns Paginated results with data, total count, and hasMore flag
|
|
2504
|
+
* @example
|
|
2505
|
+
* // With JSONB type override:
|
|
2506
|
+
* const users = await client.list<{ metadata: Metadata }>({ where: { status: 'active' } });
|
|
2501
2507
|
*/
|
|
2502
|
-
async list(params?: {
|
|
2503
|
-
include?: any;
|
|
2504
|
-
limit?: number;
|
|
2505
|
-
offset?: number;
|
|
2506
|
-
where?: Where<Select${Type}>;
|
|
2507
|
-
orderBy?: string | string[];
|
|
2508
|
-
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2509
|
-
}): Promise<PaginatedResponse<Select${Type}>>;${hasVectorColumns ? `
|
|
2510
|
-
/**
|
|
2511
|
-
* List ${table.name} records with vector similarity search
|
|
2512
|
-
* @param params - Query parameters with vector search enabled
|
|
2513
|
-
* @param params.vector - Vector similarity search configuration
|
|
2514
|
-
* @returns Paginated results with _distance field included
|
|
2515
|
-
*/
|
|
2516
|
-
async list(params: {
|
|
2508
|
+
async list<TJsonb extends Partial<Select${Type}> = {}>(params?: {
|
|
2517
2509
|
include?: any;
|
|
2518
2510
|
limit?: number;
|
|
2519
2511
|
offset?: number;
|
|
2520
|
-
where?: Where<Select${Type}
|
|
2521
|
-
vector
|
|
2512
|
+
where?: Where<Select${Type}<TJsonb>>;${hasVectorColumns ? `
|
|
2513
|
+
vector?: {
|
|
2522
2514
|
field: string;
|
|
2523
2515
|
query: number[];
|
|
2524
2516
|
metric?: "cosine" | "l2" | "inner";
|
|
2525
2517
|
maxDistance?: number;
|
|
2526
|
-
}
|
|
2518
|
+
};` : ""}
|
|
2527
2519
|
orderBy?: string | string[];
|
|
2528
2520
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2529
|
-
}): Promise<PaginatedResponse<Select${Type} & { _distance
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
*
|
|
2533
|
-
* @
|
|
2521
|
+
}): Promise<PaginatedResponse<Select${Type}<TJsonb>${hasVectorColumns ? " & { _distance?: number }" : ""}>> {
|
|
2522
|
+
return this.post<PaginatedResponse<Select${Type}<TJsonb>${hasVectorColumns ? " & { _distance?: number }" : ""}>>(\`\${this.resource}/list\`, params ?? {});
|
|
2523
|
+
}` : ` /**
|
|
2524
|
+
* List ${table.name} records with pagination and filtering
|
|
2525
|
+
* @param params - Query parameters
|
|
2526
|
+
* @param params.where - Filter conditions using operators like $eq, $gt, $in, $like, etc.
|
|
2527
|
+
* @param params.orderBy - Column(s) to sort by
|
|
2528
|
+
* @param params.order - Sort direction(s): "asc" or "desc"
|
|
2529
|
+
* @param params.limit - Maximum number of records to return (default: 50, max: 100)
|
|
2530
|
+
* @param params.offset - Number of records to skip for pagination
|
|
2531
|
+
* @param params.include - Related records to include (see listWith* methods for typed includes)
|
|
2532
|
+
* @returns Paginated results with data, total count, and hasMore flag
|
|
2534
2533
|
*/
|
|
2535
|
-
async list
|
|
2534
|
+
async list(params?: {
|
|
2536
2535
|
include?: any;
|
|
2537
2536
|
limit?: number;
|
|
2538
2537
|
offset?: number;
|
|
2539
|
-
where?: Where<
|
|
2538
|
+
where?: Where<Select${Type}>;${hasVectorColumns ? `
|
|
2540
2539
|
vector?: {
|
|
2541
2540
|
field: string;
|
|
2542
2541
|
query: number[];
|
|
@@ -2545,51 +2544,58 @@ export class ${Type}Client extends BaseClient {
|
|
|
2545
2544
|
};` : ""}
|
|
2546
2545
|
orderBy?: string | string[];
|
|
2547
2546
|
order?: "asc" | "desc" | ("asc" | "desc")[];
|
|
2548
|
-
}): Promise<PaginatedResponse<
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
}
|
|
2547
|
+
}): Promise<PaginatedResponse<Select${Type}${hasVectorColumns ? " & { _distance?: number }" : ""}>> {
|
|
2548
|
+
return this.post<PaginatedResponse<Select${Type}${hasVectorColumns ? " & { _distance?: number }" : ""}>>(\`\${this.resource}/list\`, params ?? {});
|
|
2549
|
+
}`}
|
|
2552
2550
|
|
|
2553
|
-
/**
|
|
2551
|
+
${hasJsonbColumns ? ` /**
|
|
2554
2552
|
* Update a ${table.name} record by primary key
|
|
2555
2553
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2556
2554
|
* @param patch - Partial data to update
|
|
2557
2555
|
* @returns The updated record if found, null otherwise
|
|
2556
|
+
* @example
|
|
2557
|
+
* // With JSONB type override:
|
|
2558
|
+
* const user = await client.update<{ metadata: Metadata }>('user-id', { metadata: { tags: ['new'] } });
|
|
2558
2559
|
*/
|
|
2559
|
-
async update
|
|
2560
|
-
|
|
2561
|
-
|
|
2560
|
+
async update<TJsonb extends Partial<Select${Type}> = {}>(
|
|
2561
|
+
pk: ${pkType},
|
|
2562
|
+
patch: Update${Type}<TJsonb>
|
|
2563
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
2564
|
+
const path = ${pkPathExpr};
|
|
2565
|
+
return this.patch<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`, patch);
|
|
2566
|
+
}` : ` /**
|
|
2567
|
+
* Update a ${table.name} record by primary key
|
|
2562
2568
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2563
|
-
* @param patch - Partial data to update
|
|
2564
|
-
* @returns The updated record
|
|
2569
|
+
* @param patch - Partial data to update
|
|
2570
|
+
* @returns The updated record if found, null otherwise
|
|
2565
2571
|
*/
|
|
2566
|
-
async update
|
|
2567
|
-
pk: ${pkType},
|
|
2568
|
-
patch: MergeJsonb<Update${Type}, TJsonb>
|
|
2569
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
2570
|
-
async update(pk: ${pkType}, patch: any): Promise<any> {
|
|
2572
|
+
async update(pk: ${pkType}, patch: Update${Type}): Promise<Select${Type} | null> {
|
|
2571
2573
|
const path = ${pkPathExpr};
|
|
2572
|
-
return this.patch<
|
|
2573
|
-
}
|
|
2574
|
+
return this.patch<Select${Type} | null>(\`\${this.resource}/\${path}\`, patch);
|
|
2575
|
+
}`}
|
|
2574
2576
|
|
|
2575
|
-
/**
|
|
2577
|
+
${hasJsonbColumns ? ` /**
|
|
2576
2578
|
* Delete a ${table.name} record by primary key
|
|
2577
2579
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2578
2580
|
* @returns The deleted record if found, null otherwise
|
|
2581
|
+
* @example
|
|
2582
|
+
* // With JSONB type override:
|
|
2583
|
+
* const user = await client.delete<{ metadata: Metadata }>('user-id');
|
|
2579
2584
|
*/
|
|
2580
|
-
async delete
|
|
2581
|
-
|
|
2582
|
-
|
|
2585
|
+
async delete<TJsonb extends Partial<Select${Type}> = {}>(
|
|
2586
|
+
pk: ${pkType}
|
|
2587
|
+
): Promise<Select${Type}<TJsonb> | null> {
|
|
2588
|
+
const path = ${pkPathExpr};
|
|
2589
|
+
return this.del<Select${Type}<TJsonb> | null>(\`\${this.resource}/\${path}\`);
|
|
2590
|
+
}` : ` /**
|
|
2591
|
+
* Delete a ${table.name} record by primary key
|
|
2583
2592
|
* @param pk - The primary key value${hasCompositePk ? "s" : ""}
|
|
2584
|
-
* @returns The deleted record
|
|
2593
|
+
* @returns The deleted record if found, null otherwise
|
|
2585
2594
|
*/
|
|
2586
|
-
async delete
|
|
2587
|
-
pk: ${pkType}
|
|
2588
|
-
): Promise<MergeJsonb<Select${Type}, TJsonb> | null>;
|
|
2589
|
-
async delete(pk: ${pkType}): Promise<any> {
|
|
2595
|
+
async delete(pk: ${pkType}): Promise<Select${Type} | null> {
|
|
2590
2596
|
const path = ${pkPathExpr};
|
|
2591
|
-
return this.del<
|
|
2592
|
-
}
|
|
2597
|
+
return this.del<Select${Type} | null>(\`\${this.resource}/\${path}\`);
|
|
2598
|
+
}`}
|
|
2593
2599
|
${includeMethodsCode}}
|
|
2594
2600
|
`;
|
|
2595
2601
|
}
|
|
@@ -3157,9 +3163,14 @@ function tsTypeFor(pgType, opts, enums) {
|
|
|
3157
3163
|
return "unknown";
|
|
3158
3164
|
return "string";
|
|
3159
3165
|
}
|
|
3166
|
+
function isJsonbType2(pgType) {
|
|
3167
|
+
const t = pgType.toLowerCase();
|
|
3168
|
+
return t === "json" || t === "jsonb";
|
|
3169
|
+
}
|
|
3160
3170
|
var pascal2 = (s) => s.split(/[_\s-]+/).map((w) => w?.[0] ? w[0].toUpperCase() + w.slice(1) : "").join("");
|
|
3161
3171
|
function emitTypes(table, opts, enums) {
|
|
3162
3172
|
const Type = pascal2(table.name);
|
|
3173
|
+
const hasJsonbColumns = table.columns.some((col) => isJsonbType2(col.pgType));
|
|
3163
3174
|
const insertFields = table.columns.map((col) => {
|
|
3164
3175
|
const base = tsTypeFor(col.pgType, opts, enums);
|
|
3165
3176
|
const optional = col.hasDefault || col.nullable ? "?" : "";
|
|
@@ -3173,6 +3184,57 @@ function emitTypes(table, opts, enums) {
|
|
|
3173
3184
|
return ` ${col.name}: ${valueType};`;
|
|
3174
3185
|
}).join(`
|
|
3175
3186
|
`);
|
|
3187
|
+
const baseInsertType = `type _Insert${Type}Base = {
|
|
3188
|
+
${insertFields}
|
|
3189
|
+
};`;
|
|
3190
|
+
const baseSelectType = `type _Select${Type}Base = {
|
|
3191
|
+
${selectFields}
|
|
3192
|
+
};`;
|
|
3193
|
+
if (hasJsonbColumns) {
|
|
3194
|
+
return `/**
|
|
3195
|
+
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
3196
|
+
*
|
|
3197
|
+
* This file was automatically generated by PostgreSDK.
|
|
3198
|
+
* Any manual changes will be overwritten on the next generation.
|
|
3199
|
+
*
|
|
3200
|
+
* To make changes, modify your schema or configuration and regenerate.
|
|
3201
|
+
*/
|
|
3202
|
+
|
|
3203
|
+
${baseInsertType}
|
|
3204
|
+
|
|
3205
|
+
${baseSelectType}
|
|
3206
|
+
|
|
3207
|
+
/**
|
|
3208
|
+
* Type for inserting a new ${table.name} record.
|
|
3209
|
+
* Fields with defaults or nullable columns are optional.
|
|
3210
|
+
*
|
|
3211
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
3212
|
+
* @example Insert${Type}<{ metadata: MyMetadataType }>
|
|
3213
|
+
*/
|
|
3214
|
+
export type Insert${Type}<TJsonb extends Partial<_Insert${Type}Base> = {}> =
|
|
3215
|
+
Omit<_Insert${Type}Base, keyof TJsonb> & TJsonb;
|
|
3216
|
+
|
|
3217
|
+
/**
|
|
3218
|
+
* Type for updating an existing ${table.name} record.
|
|
3219
|
+
* All fields are optional, allowing partial updates.
|
|
3220
|
+
*
|
|
3221
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
3222
|
+
* @example Update${Type}<{ metadata: MyMetadataType }>
|
|
3223
|
+
*/
|
|
3224
|
+
export type Update${Type}<TJsonb extends Partial<_Select${Type}Base> = {}> =
|
|
3225
|
+
Partial<Omit<_Insert${Type}Base, keyof TJsonb> & TJsonb>;
|
|
3226
|
+
|
|
3227
|
+
/**
|
|
3228
|
+
* Type representing a ${table.name} record from the database.
|
|
3229
|
+
* All fields are included as returned by SELECT queries.
|
|
3230
|
+
*
|
|
3231
|
+
* Generic parameter TJsonb allows overriding JSONB column types:
|
|
3232
|
+
* @example Select${Type}<{ metadata: MyMetadataType }>
|
|
3233
|
+
*/
|
|
3234
|
+
export type Select${Type}<TJsonb extends Partial<_Select${Type}Base> = {}> =
|
|
3235
|
+
Omit<_Select${Type}Base, keyof TJsonb> & TJsonb;
|
|
3236
|
+
`;
|
|
3237
|
+
}
|
|
3176
3238
|
return `/**
|
|
3177
3239
|
* AUTO-GENERATED FILE - DO NOT EDIT
|
|
3178
3240
|
*
|