postgresdk 0.3.0 → 0.4.0

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 CHANGED
@@ -493,6 +493,114 @@ const sdk = new SDK({
493
493
  });
494
494
  ```
495
495
 
496
+ ## Database Drivers
497
+
498
+ The generated code works with any PostgreSQL client that implements a simple `query` interface. You can use the standard `pg` driver, Neon's serverless driver, or any other compatible client.
499
+
500
+ ### Node.js `pg` Driver
501
+
502
+ The standard PostgreSQL driver for Node.js environments. Works everywhere Node.js runs.
503
+
504
+ Server setup:
505
+ ```typescript
506
+ import { Hono } from "hono";
507
+ import { Client } from "pg";
508
+ import { createRouter } from "./generated/server/router";
509
+
510
+ const app = new Hono();
511
+
512
+ // Standard pg client
513
+ const pg = new Client({ connectionString: process.env.DATABASE_URL });
514
+ await pg.connect();
515
+
516
+ // Wire up the generated routes
517
+ const apiRouter = createRouter({ pg });
518
+ app.route("/", apiRouter);
519
+ ```
520
+
521
+ ### Neon Serverless Driver (Edge-Compatible)
522
+
523
+ For edge environments like Vercel Edge Functions or Cloudflare Workers. Uses HTTP/WebSocket instead of TCP connections.
524
+
525
+ Server setup:
526
+ ```typescript
527
+ import { Hono } from "hono";
528
+ import { Pool } from "@neondatabase/serverless";
529
+ import { createRouter } from "./generated/server/router";
530
+
531
+ const app = new Hono();
532
+
533
+ // Neon's Pool is compatible with node-postgres
534
+ const pool = new Pool({ connectionString: process.env.DATABASE_URL! });
535
+
536
+ // Wire up the generated routes (Pool has the same query interface)
537
+ const apiRouter = createRouter({ pg: pool });
538
+ app.route("/", apiRouter);
539
+
540
+ // Deploy to Vercel Edge
541
+ export const config = { runtime: 'edge' };
542
+ export default app;
543
+ ```
544
+
545
+ ### Which Driver Should I Use?
546
+
547
+ - **Use `pg` (default) when:**
548
+ - Running on traditional Node.js servers
549
+ - Using Docker, VPS, or dedicated hosting
550
+ - Need connection pooling or advanced PostgreSQL features
551
+ - Running on AWS Lambda, Google Cloud Functions (with Node.js runtime)
552
+
553
+ - **Use `neon` when:**
554
+ - Deploying to Vercel Edge Functions
555
+ - Deploying to Cloudflare Workers
556
+ - Need globally distributed edge computing
557
+ - Want to avoid TCP connection overhead
558
+ - Using Neon as your PostgreSQL provider
559
+
560
+ ### Connection Pooling with `pg`
561
+
562
+ For production Node.js deployments, use connection pooling:
563
+
564
+ ```typescript
565
+ import { Pool } from "pg";
566
+ import { createRouter } from "./generated/server/router";
567
+
568
+ const pool = new Pool({
569
+ connectionString: process.env.DATABASE_URL,
570
+ max: 20,
571
+ idleTimeoutMillis: 30000,
572
+ connectionTimeoutMillis: 2000,
573
+ });
574
+
575
+ // The generated routes work with both Client and Pool
576
+ const apiRouter = createRouter({ pg: pool });
577
+ ```
578
+
579
+ ### Custom Database Adapters
580
+
581
+ You can use any database client as long as it matches the expected interface:
582
+
583
+ ```typescript
584
+ // Any client that implements this interface works
585
+ interface DatabaseAdapter {
586
+ query(text: string, params?: any[]): Promise<{ rows: any[] }>;
587
+ }
588
+
589
+ // Both pg and @neondatabase/serverless Pool/Client implement this interface natively
590
+ // For other ORMs, you may need to create an adapter:
591
+
592
+ // Example with a hypothetical ORM that doesn't match the interface
593
+ const customClient = new SomeORM();
594
+ const pg = {
595
+ async query(text: string, params?: any[]) {
596
+ const result = await customClient.raw(text, params);
597
+ return { rows: result };
598
+ }
599
+ };
600
+
601
+ const apiRouter = createRouter({ pg });
602
+ ```
603
+
496
604
  ## Server Integration with Hono
497
605
 
498
606
  The generated code integrates seamlessly with [Hono](https://hono.dev/), a lightweight web framework for the Edge.
package/dist/cli.js CHANGED
@@ -569,14 +569,6 @@ export default {
569
569
  */
570
570
  // dateType: "date",
571
571
 
572
- /**
573
- * Database driver to use for connection
574
- * - "pg": Node.js pg driver (default, works anywhere Node.js runs)
575
- * - "neon": Neon serverless driver (edge-compatible, works on Vercel Edge/Cloudflare Workers)
576
- * @default "pg"
577
- */
578
- // driver: "pg",
579
-
580
572
  // ========== AUTHENTICATION ==========
581
573
 
582
574
  /**
@@ -1257,7 +1249,7 @@ export class ${Type}Client extends BaseClient {
1257
1249
  function emitClientIndex(tables) {
1258
1250
  let out = `/* Generated. Do not edit. */
1259
1251
  `;
1260
- out += `import { BaseClient, AuthConfig } from "./base-client";
1252
+ out += `import { BaseClient, type AuthConfig } from "./base-client";
1261
1253
  `;
1262
1254
  for (const t of tables) {
1263
1255
  out += `import { ${pascal(t.name)}Client } from "./${t.name}";
@@ -1983,7 +1975,7 @@ export async function authMiddleware(c: Context, next: Next) {
1983
1975
  }
1984
1976
 
1985
1977
  // src/emit-router.ts
1986
- function emitRouter(tables, hasAuth, driver = "pg") {
1978
+ function emitRouter(tables, hasAuth) {
1987
1979
  const tableNames = tables.map((t) => t.name).sort();
1988
1980
  const imports = tableNames.map((name) => {
1989
1981
  const Type = pascal(name);
@@ -2000,34 +1992,6 @@ function emitRouter(tables, hasAuth, driver = "pg") {
2000
1992
  return `export { register${Type}Routes } from "./routes/${name}";`;
2001
1993
  }).join(`
2002
1994
  `);
2003
- const pgExample = driver === "pg" ? `
2004
- * import { Client } from "pg";
2005
- * import { createRouter } from "./generated/server/router";
2006
- *
2007
- * const app = new Hono();
2008
- * const pg = new Client({ connectionString: process.env.DATABASE_URL });
2009
- * await pg.connect();
2010
- *
2011
- * // Mount all generated routes under /api
2012
- * const apiRouter = createRouter({ pg });
2013
- * app.route("/api", apiRouter);` : `
2014
- * import { neon } from "@neondatabase/serverless";
2015
- * import { createRouter } from "./generated/server/router";
2016
- *
2017
- * const app = new Hono();
2018
- * const sql = neon(process.env.DATABASE_URL!);
2019
- *
2020
- * // Create pg-compatible adapter for Neon
2021
- * const pg = {
2022
- * async query(text: string, params?: any[]) {
2023
- * const rows = await sql(text, params);
2024
- * return { rows };
2025
- * }
2026
- * };
2027
- *
2028
- * // Mount all generated routes under /api
2029
- * const apiRouter = createRouter({ pg });
2030
- * app.route("/api", apiRouter);`;
2031
1995
  return `/* Generated. Do not edit. */
2032
1996
  import { Hono } from "hono";
2033
1997
  import { SDK_MANIFEST } from "./sdk-bundle";
@@ -2038,7 +2002,23 @@ ${hasAuth ? `export { authMiddleware } from "./auth";` : ""}
2038
2002
  * Creates a Hono router with all generated routes that can be mounted into your existing app.
2039
2003
  *
2040
2004
  * @example
2041
- * import { Hono } from "hono";${pgExample}
2005
+ * import { Hono } from "hono";
2006
+ * import { createRouter } from "./generated/server/router";
2007
+ *
2008
+ * // Using pg driver (Node.js)
2009
+ * import { Client } from "pg";
2010
+ * const pg = new Client({ connectionString: process.env.DATABASE_URL });
2011
+ * await pg.connect();
2012
+ *
2013
+ * // OR using Neon driver (Edge-compatible)
2014
+ * import { Pool } from "@neondatabase/serverless";
2015
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL! });
2016
+ * const pg = pool; // Pool already has the compatible query method
2017
+ *
2018
+ * // Mount all generated routes
2019
+ * const app = new Hono();
2020
+ * const apiRouter = createRouter({ pg });
2021
+ * app.route("/api", apiRouter);
2042
2022
  *
2043
2023
  * // Or mount directly at root
2044
2024
  * const router = createRouter({ pg });
@@ -2083,24 +2063,13 @@ ${registrations}
2083
2063
  * Register all generated routes directly on an existing Hono app.
2084
2064
  *
2085
2065
  * @example
2086
- * import { Hono } from "hono";${driver === "pg" ? `
2087
- * import { Client } from "pg";
2066
+ * import { Hono } from "hono";
2088
2067
  * import { registerAllRoutes } from "./generated/server/router";
2089
2068
  *
2090
2069
  * const app = new Hono();
2091
- * const pg = new Client({ connectionString: process.env.DATABASE_URL });
2092
- * await pg.connect();` : `
2093
- * import { neon } from "@neondatabase/serverless";
2094
- * import { registerAllRoutes } from "./generated/server/router";
2095
2070
  *
2096
- * const app = new Hono();
2097
- * const sql = neon(process.env.DATABASE_URL!);
2098
- * const pg = {
2099
- * async query(text: string, params?: any[]) {
2100
- * const rows = await sql(text, params);
2101
- * return { rows };
2102
- * }
2103
- * };`}
2071
+ * // Setup database connection (see createRouter example for both pg and Neon options)
2072
+ * const pg = yourDatabaseClient;
2104
2073
  *
2105
2074
  * // Register all routes at once
2106
2075
  * registerAllRoutes(app, { pg });
@@ -2252,7 +2221,7 @@ async function generate(configPath) {
2252
2221
  });
2253
2222
  files.push({
2254
2223
  path: join(serverDir, "router.ts"),
2255
- content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none", cfg.driver || "pg")
2224
+ content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none")
2256
2225
  });
2257
2226
  const clientFiles = files.filter((f) => {
2258
2227
  return f.path.includes(clientDir);
@@ -2,4 +2,4 @@ import type { Table } from "./introspect";
2
2
  /**
3
3
  * Emits the server router file that exports helper functions for route registration
4
4
  */
5
- export declare function emitRouter(tables: Table[], hasAuth: boolean, driver?: "pg" | "neon"): string;
5
+ export declare function emitRouter(tables: Table[], hasAuth: boolean): string;
package/dist/index.js CHANGED
@@ -1012,7 +1012,7 @@ export class ${Type}Client extends BaseClient {
1012
1012
  function emitClientIndex(tables) {
1013
1013
  let out = `/* Generated. Do not edit. */
1014
1014
  `;
1015
- out += `import { BaseClient, AuthConfig } from "./base-client";
1015
+ out += `import { BaseClient, type AuthConfig } from "./base-client";
1016
1016
  `;
1017
1017
  for (const t of tables) {
1018
1018
  out += `import { ${pascal(t.name)}Client } from "./${t.name}";
@@ -1738,7 +1738,7 @@ export async function authMiddleware(c: Context, next: Next) {
1738
1738
  }
1739
1739
 
1740
1740
  // src/emit-router.ts
1741
- function emitRouter(tables, hasAuth, driver = "pg") {
1741
+ function emitRouter(tables, hasAuth) {
1742
1742
  const tableNames = tables.map((t) => t.name).sort();
1743
1743
  const imports = tableNames.map((name) => {
1744
1744
  const Type = pascal(name);
@@ -1755,34 +1755,6 @@ function emitRouter(tables, hasAuth, driver = "pg") {
1755
1755
  return `export { register${Type}Routes } from "./routes/${name}";`;
1756
1756
  }).join(`
1757
1757
  `);
1758
- const pgExample = driver === "pg" ? `
1759
- * import { Client } from "pg";
1760
- * import { createRouter } from "./generated/server/router";
1761
- *
1762
- * const app = new Hono();
1763
- * const pg = new Client({ connectionString: process.env.DATABASE_URL });
1764
- * await pg.connect();
1765
- *
1766
- * // Mount all generated routes under /api
1767
- * const apiRouter = createRouter({ pg });
1768
- * app.route("/api", apiRouter);` : `
1769
- * import { neon } from "@neondatabase/serverless";
1770
- * import { createRouter } from "./generated/server/router";
1771
- *
1772
- * const app = new Hono();
1773
- * const sql = neon(process.env.DATABASE_URL!);
1774
- *
1775
- * // Create pg-compatible adapter for Neon
1776
- * const pg = {
1777
- * async query(text: string, params?: any[]) {
1778
- * const rows = await sql(text, params);
1779
- * return { rows };
1780
- * }
1781
- * };
1782
- *
1783
- * // Mount all generated routes under /api
1784
- * const apiRouter = createRouter({ pg });
1785
- * app.route("/api", apiRouter);`;
1786
1758
  return `/* Generated. Do not edit. */
1787
1759
  import { Hono } from "hono";
1788
1760
  import { SDK_MANIFEST } from "./sdk-bundle";
@@ -1793,7 +1765,23 @@ ${hasAuth ? `export { authMiddleware } from "./auth";` : ""}
1793
1765
  * Creates a Hono router with all generated routes that can be mounted into your existing app.
1794
1766
  *
1795
1767
  * @example
1796
- * import { Hono } from "hono";${pgExample}
1768
+ * import { Hono } from "hono";
1769
+ * import { createRouter } from "./generated/server/router";
1770
+ *
1771
+ * // Using pg driver (Node.js)
1772
+ * import { Client } from "pg";
1773
+ * const pg = new Client({ connectionString: process.env.DATABASE_URL });
1774
+ * await pg.connect();
1775
+ *
1776
+ * // OR using Neon driver (Edge-compatible)
1777
+ * import { Pool } from "@neondatabase/serverless";
1778
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL! });
1779
+ * const pg = pool; // Pool already has the compatible query method
1780
+ *
1781
+ * // Mount all generated routes
1782
+ * const app = new Hono();
1783
+ * const apiRouter = createRouter({ pg });
1784
+ * app.route("/api", apiRouter);
1797
1785
  *
1798
1786
  * // Or mount directly at root
1799
1787
  * const router = createRouter({ pg });
@@ -1838,24 +1826,13 @@ ${registrations}
1838
1826
  * Register all generated routes directly on an existing Hono app.
1839
1827
  *
1840
1828
  * @example
1841
- * import { Hono } from "hono";${driver === "pg" ? `
1842
- * import { Client } from "pg";
1829
+ * import { Hono } from "hono";
1843
1830
  * import { registerAllRoutes } from "./generated/server/router";
1844
1831
  *
1845
1832
  * const app = new Hono();
1846
- * const pg = new Client({ connectionString: process.env.DATABASE_URL });
1847
- * await pg.connect();` : `
1848
- * import { neon } from "@neondatabase/serverless";
1849
- * import { registerAllRoutes } from "./generated/server/router";
1850
1833
  *
1851
- * const app = new Hono();
1852
- * const sql = neon(process.env.DATABASE_URL!);
1853
- * const pg = {
1854
- * async query(text: string, params?: any[]) {
1855
- * const rows = await sql(text, params);
1856
- * return { rows };
1857
- * }
1858
- * };`}
1834
+ * // Setup database connection (see createRouter example for both pg and Neon options)
1835
+ * const pg = yourDatabaseClient;
1859
1836
  *
1860
1837
  * // Register all routes at once
1861
1838
  * registerAllRoutes(app, { pg });
@@ -2007,7 +1984,7 @@ async function generate(configPath) {
2007
1984
  });
2008
1985
  files.push({
2009
1986
  path: join(serverDir, "router.ts"),
2010
- content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none", cfg.driver || "pg")
1987
+ content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none")
2011
1988
  });
2012
1989
  const clientFiles = files.filter((f) => {
2013
1990
  return f.path.includes(clientDir);
package/dist/types.d.ts CHANGED
@@ -26,7 +26,6 @@ export interface Config {
26
26
  softDeleteColumn?: string | null;
27
27
  includeDepthLimit?: number;
28
28
  dateType?: "date" | "string";
29
- driver?: "pg" | "neon";
30
29
  auth?: AuthConfigInput;
31
30
  pull?: PullConfig;
32
31
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {