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 +108 -0
- package/dist/cli.js +23 -54
- package/dist/emit-router.d.ts +1 -1
- package/dist/index.js +23 -46
- package/dist/types.d.ts +0 -1
- package/package.json +1 -1
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
|
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"
|
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"
|
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
|
-
*
|
2097
|
-
* const
|
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"
|
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);
|
package/dist/emit-router.d.ts
CHANGED
@@ -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
|
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
|
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"
|
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"
|
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
|
-
*
|
1852
|
-
* const
|
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"
|
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