postgresdk 0.9.2 → 0.9.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/dist/cli-config-utils.d.ts +14 -0
- package/dist/cli.js +405 -9
- package/dist/index.js +6 -2
- package/package.json +4 -2
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config } from "./types";
|
|
2
|
+
export interface ConfigField {
|
|
3
|
+
key: string;
|
|
4
|
+
value: any;
|
|
5
|
+
description: string;
|
|
6
|
+
isRequired?: boolean;
|
|
7
|
+
isCommented?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseExistingConfig(configPath: string): {
|
|
10
|
+
config: Config | null;
|
|
11
|
+
raw: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function extractConfigFields(configContent: string): ConfigField[];
|
|
14
|
+
export declare function generateMergedConfig(existingFields: ConfigField[], mergeStrategy: "keep-existing" | "use-defaults" | "interactive", userChoices?: Map<string, any> | undefined): string;
|
package/dist/cli.js
CHANGED
|
@@ -602,8 +602,12 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
602
602
|
continue;
|
|
603
603
|
const [key1, edge1] = entry1;
|
|
604
604
|
const [key2, edge2] = entry2;
|
|
605
|
-
if (opts.skipJunctionTables &&
|
|
606
|
-
|
|
605
|
+
if (opts.skipJunctionTables && allTables) {
|
|
606
|
+
const table1 = allTables.find((t) => t.name === edge1.target);
|
|
607
|
+
const table2 = allTables.find((t) => t.name === edge2.target);
|
|
608
|
+
if (table1 && isJunctionTable(table1) || table2 && isJunctionTable(table2)) {
|
|
609
|
+
continue;
|
|
610
|
+
}
|
|
607
611
|
}
|
|
608
612
|
const combinedPath = [key1, key2];
|
|
609
613
|
const combinedSuffix = `With${pascal(key1)}And${pascal(key2)}`;
|
|
@@ -1302,21 +1306,411 @@ var init_emit_sdk_contract = __esm(() => {
|
|
|
1302
1306
|
init_emit_include_methods();
|
|
1303
1307
|
});
|
|
1304
1308
|
|
|
1309
|
+
// src/cli-config-utils.ts
|
|
1310
|
+
function extractConfigFields(configContent) {
|
|
1311
|
+
const fields = [];
|
|
1312
|
+
const connectionMatch = configContent.match(/connectionString:\s*(.+),?$/m);
|
|
1313
|
+
if (connectionMatch) {
|
|
1314
|
+
fields.push({
|
|
1315
|
+
key: "connectionString",
|
|
1316
|
+
value: connectionMatch[1]?.trim(),
|
|
1317
|
+
description: "PostgreSQL connection string",
|
|
1318
|
+
isRequired: true,
|
|
1319
|
+
isCommented: false
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
const schemaMatch = configContent.match(/^\s*(\/\/)?\s*schema:\s*"(.+)"/m);
|
|
1323
|
+
if (schemaMatch) {
|
|
1324
|
+
fields.push({
|
|
1325
|
+
key: "schema",
|
|
1326
|
+
value: schemaMatch[2],
|
|
1327
|
+
description: "Database schema to introspect",
|
|
1328
|
+
isCommented: !!schemaMatch[1]
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
const outServerMatch = configContent.match(/^\s*(\/\/)?\s*outServer:\s*"(.+)"/m);
|
|
1332
|
+
if (outServerMatch) {
|
|
1333
|
+
fields.push({
|
|
1334
|
+
key: "outServer",
|
|
1335
|
+
value: outServerMatch[2],
|
|
1336
|
+
description: "Output directory for server-side code",
|
|
1337
|
+
isCommented: !!outServerMatch[1]
|
|
1338
|
+
});
|
|
1339
|
+
}
|
|
1340
|
+
const outClientMatch = configContent.match(/^\s*(\/\/)?\s*outClient:\s*"(.+)"/m);
|
|
1341
|
+
if (outClientMatch) {
|
|
1342
|
+
fields.push({
|
|
1343
|
+
key: "outClient",
|
|
1344
|
+
value: outClientMatch[2],
|
|
1345
|
+
description: "Output directory for client SDK",
|
|
1346
|
+
isCommented: !!outClientMatch[1]
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
const softDeleteMatch = configContent.match(/^\s*(\/\/)?\s*softDeleteColumn:\s*(.+),?$/m);
|
|
1350
|
+
if (softDeleteMatch) {
|
|
1351
|
+
fields.push({
|
|
1352
|
+
key: "softDeleteColumn",
|
|
1353
|
+
value: softDeleteMatch[2]?.trim().replace(/,$/, "").replace(/["']/g, ""),
|
|
1354
|
+
description: "Column name for soft deletes",
|
|
1355
|
+
isCommented: !!softDeleteMatch[1]
|
|
1356
|
+
});
|
|
1357
|
+
}
|
|
1358
|
+
const depthMatch = configContent.match(/^\s*(\/\/)?\s*includeDepthLimit:\s*(\d+)/m);
|
|
1359
|
+
if (depthMatch) {
|
|
1360
|
+
fields.push({
|
|
1361
|
+
key: "includeDepthLimit",
|
|
1362
|
+
value: parseInt(depthMatch[2]),
|
|
1363
|
+
description: "Maximum depth for nested relationship includes",
|
|
1364
|
+
isCommented: !!depthMatch[1]
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
const frameworkMatch = configContent.match(/^\s*(\/\/)?\s*serverFramework:\s*"(.+)"/m);
|
|
1368
|
+
if (frameworkMatch) {
|
|
1369
|
+
fields.push({
|
|
1370
|
+
key: "serverFramework",
|
|
1371
|
+
value: frameworkMatch[2],
|
|
1372
|
+
description: "Server framework for generated API routes",
|
|
1373
|
+
isCommented: !!frameworkMatch[1]
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
const jsExtMatch = configContent.match(/^\s*(\/\/)?\s*useJsExtensions:\s*(true|false)/m);
|
|
1377
|
+
if (jsExtMatch) {
|
|
1378
|
+
fields.push({
|
|
1379
|
+
key: "useJsExtensions",
|
|
1380
|
+
value: jsExtMatch[2] === "true",
|
|
1381
|
+
description: "Use .js extensions in server imports",
|
|
1382
|
+
isCommented: !!jsExtMatch[1]
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
const jsExtClientMatch = configContent.match(/^\s*(\/\/)?\s*useJsExtensionsClient:\s*(true|false)/m);
|
|
1386
|
+
if (jsExtClientMatch) {
|
|
1387
|
+
fields.push({
|
|
1388
|
+
key: "useJsExtensionsClient",
|
|
1389
|
+
value: jsExtClientMatch[2] === "true",
|
|
1390
|
+
description: "Use .js extensions in client SDK imports",
|
|
1391
|
+
isCommented: !!jsExtClientMatch[1]
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1394
|
+
const testsMatch = configContent.match(/^\s*(\/\/)?\s*tests:\s*\{/m);
|
|
1395
|
+
if (testsMatch) {
|
|
1396
|
+
fields.push({
|
|
1397
|
+
key: "tests",
|
|
1398
|
+
value: "configured",
|
|
1399
|
+
description: "Test generation configuration",
|
|
1400
|
+
isCommented: !!testsMatch[1]
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
const authMatch = configContent.match(/^\s*(\/\/)?\s*auth:\s*\{/m);
|
|
1404
|
+
if (authMatch) {
|
|
1405
|
+
fields.push({
|
|
1406
|
+
key: "auth",
|
|
1407
|
+
value: "configured",
|
|
1408
|
+
description: "Authentication configuration",
|
|
1409
|
+
isCommented: !!authMatch[1]
|
|
1410
|
+
});
|
|
1411
|
+
}
|
|
1412
|
+
const pullMatch = configContent.match(/^\s*(\/\/)?\s*pull:\s*\{/m);
|
|
1413
|
+
if (pullMatch) {
|
|
1414
|
+
fields.push({
|
|
1415
|
+
key: "pull",
|
|
1416
|
+
value: "configured",
|
|
1417
|
+
description: "SDK distribution configuration",
|
|
1418
|
+
isCommented: !!pullMatch[1]
|
|
1419
|
+
});
|
|
1420
|
+
}
|
|
1421
|
+
return fields;
|
|
1422
|
+
}
|
|
1423
|
+
function generateMergedConfig(existingFields, mergeStrategy, userChoices = undefined) {
|
|
1424
|
+
const template = `/**
|
|
1425
|
+
* PostgreSDK Configuration
|
|
1426
|
+
*
|
|
1427
|
+
* This file configures how postgresdk generates your SDK.
|
|
1428
|
+
* Environment variables are automatically loaded from .env files.
|
|
1429
|
+
*/
|
|
1430
|
+
|
|
1431
|
+
export default {
|
|
1432
|
+
// ========== DATABASE CONNECTION (Required) ==========
|
|
1433
|
+
|
|
1434
|
+
/**
|
|
1435
|
+
* PostgreSQL connection string
|
|
1436
|
+
* Format: postgres://user:password@host:port/database
|
|
1437
|
+
*/
|
|
1438
|
+
connectionString: ${getFieldValue("connectionString", existingFields, mergeStrategy, userChoices)},
|
|
1439
|
+
|
|
1440
|
+
// ========== BASIC OPTIONS ==========
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* Database schema to introspect
|
|
1444
|
+
* @default "public"
|
|
1445
|
+
*/
|
|
1446
|
+
${getFieldLine("schema", existingFields, mergeStrategy, '"public"', userChoices)}
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* Output directory for server-side code (routes, validators, etc.)
|
|
1450
|
+
* @default "./api/server"
|
|
1451
|
+
*/
|
|
1452
|
+
${getFieldLine("outServer", existingFields, mergeStrategy, '"./api/server"', userChoices)}
|
|
1453
|
+
|
|
1454
|
+
/**
|
|
1455
|
+
* Output directory for client SDK
|
|
1456
|
+
* @default "./api/client"
|
|
1457
|
+
*/
|
|
1458
|
+
${getFieldLine("outClient", existingFields, mergeStrategy, '"./api/client"', userChoices)}
|
|
1459
|
+
|
|
1460
|
+
// ========== ADVANCED OPTIONS ==========
|
|
1461
|
+
|
|
1462
|
+
/**
|
|
1463
|
+
* Column name for soft deletes. When set, DELETE operations will update
|
|
1464
|
+
* this column instead of removing rows.
|
|
1465
|
+
* @default null (hard deletes)
|
|
1466
|
+
* @example "deleted_at"
|
|
1467
|
+
*/
|
|
1468
|
+
${getFieldLine("softDeleteColumn", existingFields, mergeStrategy, "null", userChoices)}
|
|
1469
|
+
|
|
1470
|
+
/**
|
|
1471
|
+
* Maximum depth for nested relationship includes to prevent infinite loops
|
|
1472
|
+
* @default 3
|
|
1473
|
+
*/
|
|
1474
|
+
${getFieldLine("includeDepthLimit", existingFields, mergeStrategy, "3", userChoices)}
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* Server framework for generated API routes
|
|
1479
|
+
* - "hono": Lightweight, edge-compatible web framework (default)
|
|
1480
|
+
* - "express": Traditional Node.js framework (planned)
|
|
1481
|
+
* - "fastify": High-performance Node.js framework (planned)
|
|
1482
|
+
* @default "hono"
|
|
1483
|
+
*/
|
|
1484
|
+
${getFieldLine("serverFramework", existingFields, mergeStrategy, '"hono"', userChoices)}
|
|
1485
|
+
|
|
1486
|
+
/**
|
|
1487
|
+
* Use .js extensions in server imports (for Vercel Edge, Deno, etc.)
|
|
1488
|
+
* @default false
|
|
1489
|
+
*/
|
|
1490
|
+
${getFieldLine("useJsExtensions", existingFields, mergeStrategy, "false", userChoices)}
|
|
1491
|
+
|
|
1492
|
+
/**
|
|
1493
|
+
* Use .js extensions in client SDK imports (rarely needed)
|
|
1494
|
+
* @default false
|
|
1495
|
+
*/
|
|
1496
|
+
${getFieldLine("useJsExtensionsClient", existingFields, mergeStrategy, "false", userChoices)}
|
|
1497
|
+
|
|
1498
|
+
// ========== TEST GENERATION ==========
|
|
1499
|
+
|
|
1500
|
+
/**
|
|
1501
|
+
* Generate basic SDK tests
|
|
1502
|
+
* Uncomment to enable test generation with Docker setup
|
|
1503
|
+
*/
|
|
1504
|
+
// tests: {
|
|
1505
|
+
// generate: true,
|
|
1506
|
+
// output: "./api/tests",
|
|
1507
|
+
// framework: "vitest" // or "jest" or "bun"
|
|
1508
|
+
// },
|
|
1509
|
+
|
|
1510
|
+
// ========== AUTHENTICATION ==========
|
|
1511
|
+
|
|
1512
|
+
/**
|
|
1513
|
+
* Authentication configuration for your API
|
|
1514
|
+
*
|
|
1515
|
+
* Simple syntax examples:
|
|
1516
|
+
* auth: { apiKey: process.env.API_KEY }
|
|
1517
|
+
* auth: { jwt: process.env.JWT_SECRET }
|
|
1518
|
+
*
|
|
1519
|
+
* Multiple API keys:
|
|
1520
|
+
* auth: { apiKeys: [process.env.KEY1, process.env.KEY2] }
|
|
1521
|
+
*
|
|
1522
|
+
* Full syntax for advanced options:
|
|
1523
|
+
*/
|
|
1524
|
+
// auth: {
|
|
1525
|
+
// // Strategy: "none" | "api-key" | "jwt-hs256"
|
|
1526
|
+
// strategy: "none",
|
|
1527
|
+
//
|
|
1528
|
+
// // For API Key authentication
|
|
1529
|
+
// apiKeyHeader: "x-api-key", // Header name for API key
|
|
1530
|
+
// apiKeys: [ // List of valid API keys
|
|
1531
|
+
// process.env.API_KEY_1,
|
|
1532
|
+
// process.env.API_KEY_2,
|
|
1533
|
+
// ],
|
|
1534
|
+
//
|
|
1535
|
+
// // For JWT (HS256) authentication
|
|
1536
|
+
// jwt: {
|
|
1537
|
+
// sharedSecret: process.env.JWT_SECRET, // Secret for signing/verifying
|
|
1538
|
+
// issuer: "my-app", // Optional: validate 'iss' claim
|
|
1539
|
+
// audience: "my-users", // Optional: validate 'aud' claim
|
|
1540
|
+
// }
|
|
1541
|
+
// },
|
|
1542
|
+
|
|
1543
|
+
// ========== SDK DISTRIBUTION (Pull Configuration) ==========
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Configuration for pulling SDK from a remote API
|
|
1547
|
+
* Used when running 'postgresdk pull' command
|
|
1548
|
+
*/
|
|
1549
|
+
// pull: {
|
|
1550
|
+
// from: "https://api.myapp.com", // API URL to pull SDK from
|
|
1551
|
+
// output: "./src/sdk", // Local directory for pulled SDK
|
|
1552
|
+
// token: process.env.API_TOKEN, // Optional authentication token
|
|
1553
|
+
// },
|
|
1554
|
+
};
|
|
1555
|
+
`;
|
|
1556
|
+
return template;
|
|
1557
|
+
}
|
|
1558
|
+
function getFieldValue(key, existingFields, mergeStrategy, userChoices) {
|
|
1559
|
+
const existing = existingFields.find((f) => f.key === key);
|
|
1560
|
+
if (mergeStrategy === "keep-existing" && existing && !existing.isCommented) {
|
|
1561
|
+
const value = existing.value.toString().replace(/,\s*$/, "");
|
|
1562
|
+
return value;
|
|
1563
|
+
}
|
|
1564
|
+
if (mergeStrategy === "interactive" && userChoices?.has(key)) {
|
|
1565
|
+
return userChoices.get(key);
|
|
1566
|
+
}
|
|
1567
|
+
return 'process.env.DATABASE_URL || "postgres://user:password@localhost:5432/mydb"';
|
|
1568
|
+
}
|
|
1569
|
+
function getFieldLine(key, existingFields, mergeStrategy, defaultValue, userChoices) {
|
|
1570
|
+
const existing = existingFields.find((f) => f.key === key);
|
|
1571
|
+
const shouldUseExisting = mergeStrategy === "keep-existing" && existing && !existing.isCommented || mergeStrategy === "interactive" && userChoices?.get(key) === "keep";
|
|
1572
|
+
const shouldUseNew = mergeStrategy === "use-defaults" || mergeStrategy === "interactive" && userChoices?.get(key) === "new";
|
|
1573
|
+
if (shouldUseExisting && existing) {
|
|
1574
|
+
const value = typeof existing.value === "string" && !existing.value.startsWith('"') ? `"${existing.value}"` : existing.value;
|
|
1575
|
+
return `${key}: ${value},`;
|
|
1576
|
+
}
|
|
1577
|
+
if (shouldUseNew) {
|
|
1578
|
+
return `${key}: ${defaultValue},`;
|
|
1579
|
+
}
|
|
1580
|
+
return `// ${key}: ${defaultValue},`;
|
|
1581
|
+
}
|
|
1582
|
+
var init_cli_config_utils = () => {};
|
|
1583
|
+
|
|
1305
1584
|
// src/cli-init.ts
|
|
1306
1585
|
var exports_cli_init = {};
|
|
1307
1586
|
__export(exports_cli_init, {
|
|
1308
1587
|
initCommand: () => initCommand
|
|
1309
1588
|
});
|
|
1310
|
-
import { existsSync, writeFileSync } from "fs";
|
|
1589
|
+
import { existsSync, writeFileSync, readFileSync, copyFileSync } from "fs";
|
|
1311
1590
|
import { resolve } from "path";
|
|
1591
|
+
import prompts from "prompts";
|
|
1312
1592
|
async function initCommand(args) {
|
|
1313
1593
|
console.log(`\uD83D\uDE80 Initializing postgresdk configuration...
|
|
1314
1594
|
`);
|
|
1595
|
+
const forceError = args.includes("--force-error");
|
|
1315
1596
|
const configPath = resolve(process.cwd(), "postgresdk.config.ts");
|
|
1316
1597
|
if (existsSync(configPath)) {
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1598
|
+
if (forceError) {
|
|
1599
|
+
console.error("❌ Error: postgresdk.config.ts already exists");
|
|
1600
|
+
console.log(" To reinitialize, please remove or rename the existing file first.");
|
|
1601
|
+
process.exit(1);
|
|
1602
|
+
}
|
|
1603
|
+
console.log(`⚠️ Found existing postgresdk.config.ts
|
|
1604
|
+
`);
|
|
1605
|
+
const existingContent = readFileSync(configPath, "utf-8");
|
|
1606
|
+
const existingFields = extractConfigFields(existingContent);
|
|
1607
|
+
console.log("\uD83D\uDCCB Existing configuration detected:");
|
|
1608
|
+
existingFields.forEach((field) => {
|
|
1609
|
+
if (!field.isCommented) {
|
|
1610
|
+
console.log(` • ${field.description}: ${field.value}`);
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
console.log();
|
|
1614
|
+
const { mergeStrategy } = await prompts({
|
|
1615
|
+
type: "select",
|
|
1616
|
+
name: "mergeStrategy",
|
|
1617
|
+
message: "How would you like to proceed?",
|
|
1618
|
+
choices: [
|
|
1619
|
+
{
|
|
1620
|
+
title: "Keep existing values and add new options",
|
|
1621
|
+
value: "keep-existing",
|
|
1622
|
+
description: "Preserves your current settings while adding any new configuration options"
|
|
1623
|
+
},
|
|
1624
|
+
{
|
|
1625
|
+
title: "Interactive merge (recommended)",
|
|
1626
|
+
value: "interactive",
|
|
1627
|
+
description: "Review each setting and choose what to keep"
|
|
1628
|
+
},
|
|
1629
|
+
{
|
|
1630
|
+
title: "Replace with fresh defaults",
|
|
1631
|
+
value: "use-defaults",
|
|
1632
|
+
description: "Creates a new config with default values (backs up existing)"
|
|
1633
|
+
},
|
|
1634
|
+
{
|
|
1635
|
+
title: "Cancel",
|
|
1636
|
+
value: "cancel",
|
|
1637
|
+
description: "Exit without making changes"
|
|
1638
|
+
}
|
|
1639
|
+
],
|
|
1640
|
+
initial: 1
|
|
1641
|
+
});
|
|
1642
|
+
if (!mergeStrategy || mergeStrategy === "cancel") {
|
|
1643
|
+
console.log(`
|
|
1644
|
+
✅ Cancelled. No changes made.`);
|
|
1645
|
+
process.exit(0);
|
|
1646
|
+
}
|
|
1647
|
+
let userChoices;
|
|
1648
|
+
if (mergeStrategy === "interactive") {
|
|
1649
|
+
userChoices = new Map;
|
|
1650
|
+
console.log(`
|
|
1651
|
+
\uD83D\uDD04 Let's review your configuration:
|
|
1652
|
+
`);
|
|
1653
|
+
for (const field of existingFields.filter((f) => !f.isCommented)) {
|
|
1654
|
+
const { choice } = await prompts({
|
|
1655
|
+
type: "select",
|
|
1656
|
+
name: "choice",
|
|
1657
|
+
message: `${field.description}:
|
|
1658
|
+
Current: ${field.value}
|
|
1659
|
+
Action:`,
|
|
1660
|
+
choices: [
|
|
1661
|
+
{ title: "Keep current value", value: "keep" },
|
|
1662
|
+
{ title: "Use default value", value: "new" }
|
|
1663
|
+
],
|
|
1664
|
+
initial: 0
|
|
1665
|
+
});
|
|
1666
|
+
if (!choice) {
|
|
1667
|
+
console.log(`
|
|
1668
|
+
✅ Cancelled. No changes made.`);
|
|
1669
|
+
process.exit(0);
|
|
1670
|
+
}
|
|
1671
|
+
userChoices.set(field.key, choice);
|
|
1672
|
+
}
|
|
1673
|
+
const newOptions = [
|
|
1674
|
+
{ key: "tests", description: "Enable test generation" },
|
|
1675
|
+
{ key: "auth", description: "Add authentication" },
|
|
1676
|
+
{ key: "pull", description: "Configure SDK distribution" }
|
|
1677
|
+
];
|
|
1678
|
+
const existingKeys = new Set(existingFields.map((f) => f.key));
|
|
1679
|
+
const missingOptions = newOptions.filter((opt) => !existingKeys.has(opt.key));
|
|
1680
|
+
if (missingOptions.length > 0) {
|
|
1681
|
+
console.log(`
|
|
1682
|
+
\uD83D\uDCE6 New configuration options available:
|
|
1683
|
+
`);
|
|
1684
|
+
for (const option of missingOptions) {
|
|
1685
|
+
const { addOption } = await prompts({
|
|
1686
|
+
type: "confirm",
|
|
1687
|
+
name: "addOption",
|
|
1688
|
+
message: `Add ${option.description} configuration? (commented out by default)`,
|
|
1689
|
+
initial: false
|
|
1690
|
+
});
|
|
1691
|
+
if (addOption) {
|
|
1692
|
+
userChoices.set(option.key, "add-commented");
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
const backupPath = configPath + ".backup." + Date.now();
|
|
1698
|
+
copyFileSync(configPath, backupPath);
|
|
1699
|
+
console.log(`
|
|
1700
|
+
\uD83D\uDCBE Backed up existing config to: ${backupPath}`);
|
|
1701
|
+
const mergedConfig = generateMergedConfig(existingFields, mergeStrategy, userChoices);
|
|
1702
|
+
try {
|
|
1703
|
+
writeFileSync(configPath, mergedConfig, "utf-8");
|
|
1704
|
+
console.log("✅ Updated postgresdk.config.ts with merged configuration");
|
|
1705
|
+
console.log(`
|
|
1706
|
+
\uD83D\uDCA1 Your previous config has been backed up.`);
|
|
1707
|
+
console.log(" Run 'postgresdk generate' to create your SDK with the new config.");
|
|
1708
|
+
} catch (error) {
|
|
1709
|
+
console.error("❌ Error updating config file:", error);
|
|
1710
|
+
console.log(` Your backup is available at: ${backupPath}`);
|
|
1711
|
+
process.exit(1);
|
|
1712
|
+
}
|
|
1713
|
+
return;
|
|
1320
1714
|
}
|
|
1321
1715
|
const envPath = resolve(process.cwd(), ".env");
|
|
1322
1716
|
const hasEnv = existsSync(envPath);
|
|
@@ -1473,7 +1867,9 @@ export default {
|
|
|
1473
1867
|
// },
|
|
1474
1868
|
};
|
|
1475
1869
|
`;
|
|
1476
|
-
var init_cli_init = () => {
|
|
1870
|
+
var init_cli_init = __esm(() => {
|
|
1871
|
+
init_cli_config_utils();
|
|
1872
|
+
});
|
|
1477
1873
|
|
|
1478
1874
|
// src/cli-pull.ts
|
|
1479
1875
|
var exports_cli_pull = {};
|
|
@@ -4234,12 +4630,12 @@ async function generate(configPath) {
|
|
|
4234
4630
|
// src/cli.ts
|
|
4235
4631
|
var import_config2 = __toESM(require_config(), 1);
|
|
4236
4632
|
import { resolve as resolve3 } from "node:path";
|
|
4237
|
-
import { readFileSync } from "node:fs";
|
|
4633
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
4238
4634
|
import { fileURLToPath } from "node:url";
|
|
4239
4635
|
import { dirname as dirname3, join as join3 } from "node:path";
|
|
4240
4636
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
4241
4637
|
var __dirname2 = dirname3(__filename2);
|
|
4242
|
-
var packageJson = JSON.parse(
|
|
4638
|
+
var packageJson = JSON.parse(readFileSync2(join3(__dirname2, "../package.json"), "utf-8"));
|
|
4243
4639
|
var VERSION = packageJson.version;
|
|
4244
4640
|
var args = process.argv.slice(2);
|
|
4245
4641
|
var command = args[0];
|
package/dist/index.js
CHANGED
|
@@ -601,8 +601,12 @@ function generateIncludeMethods(table, graph, opts, allTables) {
|
|
|
601
601
|
continue;
|
|
602
602
|
const [key1, edge1] = entry1;
|
|
603
603
|
const [key2, edge2] = entry2;
|
|
604
|
-
if (opts.skipJunctionTables &&
|
|
605
|
-
|
|
604
|
+
if (opts.skipJunctionTables && allTables) {
|
|
605
|
+
const table1 = allTables.find((t) => t.name === edge1.target);
|
|
606
|
+
const table2 = allTables.find((t) => t.name === edge2.target);
|
|
607
|
+
if (table1 && isJunctionTable(table1) || table2 && isJunctionTable(table2)) {
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
606
610
|
}
|
|
607
611
|
const combinedPath = [key1, key2];
|
|
608
612
|
const combinedSuffix = `With${pascal(key1)}And${pascal(key2)}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postgresdk",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"node": ">=18.17"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"build": "bun build src/cli.ts src/index.ts --outdir dist --target node --format esm --external=pg --external=zod --external=hono --external=node:* && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
24
|
+
"build": "bun build src/cli.ts src/index.ts --outdir dist --target node --format esm --external=pg --external=zod --external=hono --external=prompts --external=node:* && tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
25
25
|
"test": "bun test:init && bun test:gen && bun test:gen-with-tests && bun test:pull && bun test:typecheck && bun test:drizzle-e2e",
|
|
26
26
|
"test:init": "bun test/test-init.ts",
|
|
27
27
|
"test:gen": "bun test/test-gen.ts",
|
|
@@ -36,9 +36,11 @@
|
|
|
36
36
|
"publish:major": "./publish.sh"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@types/prompts": "^2.4.9",
|
|
39
40
|
"dotenv": "^17.2.1",
|
|
40
41
|
"hono": "^4.9.0",
|
|
41
42
|
"pg": "^8.16.3",
|
|
43
|
+
"prompts": "^2.4.2",
|
|
42
44
|
"zod": "^4.0.15"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|