postgresdk 0.1.2-alpha.1 → 0.1.2-alpha.3

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
@@ -89,7 +89,7 @@ const recentBooks = await sdk.books.list({
89
89
  ```typescript
90
90
  import { Hono } from "hono";
91
91
  import { Client } from "pg";
92
- import { createRouter } from "./generated/server";
92
+ import { createRouter } from "./generated/server/router";
93
93
 
94
94
  const app = new Hono();
95
95
  const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -348,7 +348,23 @@ export default {
348
348
  ### API Key Authentication
349
349
 
350
350
  ```typescript
351
- // postgresdk.config.ts
351
+ // postgresdk.config.ts - Simplified syntax
352
+ export default {
353
+ connectionString: "...",
354
+ auth: {
355
+ apiKey: "your-api-key" // Single key shorthand
356
+ }
357
+ };
358
+
359
+ // Or multiple keys
360
+ export default {
361
+ connectionString: "...",
362
+ auth: {
363
+ apiKeys: ["key1", "key2", "key3"]
364
+ }
365
+ };
366
+
367
+ // Or full syntax with custom header
352
368
  export default {
353
369
  connectionString: "...",
354
370
  auth: {
@@ -373,7 +389,15 @@ const sdk = new SDK({
373
389
  ### JWT Authentication (HS256)
374
390
 
375
391
  ```typescript
376
- // postgresdk.config.ts
392
+ // postgresdk.config.ts - Simplified syntax
393
+ export default {
394
+ connectionString: "...",
395
+ auth: {
396
+ jwt: "your-secret-key" // Shared secret shorthand
397
+ }
398
+ };
399
+
400
+ // Or full syntax with issuer/audience validation
377
401
  export default {
378
402
  connectionString: "...",
379
403
  auth: {
@@ -479,7 +503,7 @@ postgresdk generates a `createRouter` function that returns a Hono router with a
479
503
  import { Hono } from "hono";
480
504
  import { serve } from "@hono/node-server";
481
505
  import { Client } from "pg";
482
- import { createRouter } from "./generated/server";
506
+ import { createRouter } from "./generated/server/router";
483
507
 
484
508
  const app = new Hono();
485
509
 
@@ -502,7 +526,7 @@ The `createRouter` function returns a Hono router that can be mounted anywhere:
502
526
 
503
527
  ```typescript
504
528
  import { Hono } from "hono";
505
- import { createRouter } from "./generated/server";
529
+ import { createRouter } from "./generated/server/router";
506
530
 
507
531
  const app = new Hono();
508
532
 
@@ -523,7 +547,7 @@ app.route("/v2", apiRouter); // Routes will be at /v2/v1/users, /v2/v1/posts,
523
547
  If you prefer to register routes directly on your app without a sub-router:
524
548
 
525
549
  ```typescript
526
- import { registerAllRoutes } from "./generated/server";
550
+ import { registerAllRoutes } from "./generated/server/router";
527
551
 
528
552
  const app = new Hono();
529
553
  const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -538,7 +562,7 @@ registerAllRoutes(app, { pg });
538
562
  You can also import and register individual routes:
539
563
 
540
564
  ```typescript
541
- import { registerUsersRoutes, registerPostsRoutes } from "./generated/server";
565
+ import { registerUsersRoutes, registerPostsRoutes } from "./generated/server/router";
542
566
 
543
567
  const app = new Hono();
544
568
 
package/dist/cli.js CHANGED
@@ -1659,8 +1659,8 @@ export async function authMiddleware(c: Context, next: Next) {
1659
1659
  `;
1660
1660
  }
1661
1661
 
1662
- // src/emit-server-index.ts
1663
- function emitServerIndex(tables, hasAuth) {
1662
+ // src/emit-router.ts
1663
+ function emitRouter(tables, hasAuth) {
1664
1664
  const tableNames = tables.map((t) => t.name).sort();
1665
1665
  const imports = tableNames.map((name) => {
1666
1666
  const Type = pascal(name);
@@ -1688,7 +1688,7 @@ ${hasAuth ? `export { authMiddleware } from "./auth";` : ""}
1688
1688
  * @example
1689
1689
  * import { Hono } from "hono";
1690
1690
  * import { Client } from "pg";
1691
- * import { createRouter } from "./generated/server";
1691
+ * import { createRouter } from "./generated/server/router";
1692
1692
  *
1693
1693
  * const app = new Hono();
1694
1694
  * const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -1716,7 +1716,7 @@ ${registrations}
1716
1716
  * @example
1717
1717
  * import { Hono } from "hono";
1718
1718
  * import { Client } from "pg";
1719
- * import { registerAllRoutes } from "./generated/server";
1719
+ * import { registerAllRoutes } from "./generated/server/router";
1720
1720
  *
1721
1721
  * const app = new Hono();
1722
1722
  * const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -1740,11 +1740,50 @@ export * from "./include-spec";
1740
1740
  `;
1741
1741
  }
1742
1742
 
1743
+ // src/types.ts
1744
+ function normalizeAuthConfig(input) {
1745
+ if (!input)
1746
+ return;
1747
+ if ("strategy" in input && input.strategy) {
1748
+ return input;
1749
+ }
1750
+ if ("apiKey" in input && input.apiKey) {
1751
+ return {
1752
+ strategy: "api-key",
1753
+ apiKeyHeader: input.apiKeyHeader,
1754
+ apiKeys: [input.apiKey, ...input.apiKeys || []]
1755
+ };
1756
+ }
1757
+ if ("apiKeys" in input && input.apiKeys?.length) {
1758
+ return {
1759
+ strategy: "api-key",
1760
+ apiKeyHeader: input.apiKeyHeader,
1761
+ apiKeys: input.apiKeys
1762
+ };
1763
+ }
1764
+ if ("jwt" in input && input.jwt) {
1765
+ if (typeof input.jwt === "string") {
1766
+ return {
1767
+ strategy: "jwt-hs256",
1768
+ jwt: { sharedSecret: input.jwt }
1769
+ };
1770
+ } else {
1771
+ return {
1772
+ strategy: "jwt-hs256",
1773
+ jwt: input.jwt
1774
+ };
1775
+ }
1776
+ }
1777
+ return { strategy: "none" };
1778
+ }
1779
+
1743
1780
  // src/index.ts
1744
1781
  async function generate(configPath) {
1745
1782
  const configUrl = pathToFileURL(configPath).href;
1746
1783
  const module = await import(configUrl);
1747
- const cfg = module.default || module;
1784
+ const rawCfg = module.default || module;
1785
+ const normalizedAuth = normalizeAuthConfig(rawCfg.auth);
1786
+ const cfg = { ...rawCfg, auth: normalizedAuth };
1748
1787
  console.log("\uD83D\uDD0D Introspecting database...");
1749
1788
  const model = await introspect(cfg.connectionString, cfg.schema || "public");
1750
1789
  console.log("\uD83D\uDD17 Building relationship graph...");
@@ -1774,8 +1813,8 @@ async function generate(configPath) {
1774
1813
  content: emitIncludeLoader(graph, model, cfg.includeDepthLimit || 3)
1775
1814
  });
1776
1815
  files.push({ path: join(serverDir, "logger.ts"), content: emitLogger() });
1777
- if (cfg.auth?.strategy && cfg.auth.strategy !== "none") {
1778
- files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(cfg.auth) });
1816
+ if (normalizedAuth?.strategy && normalizedAuth.strategy !== "none") {
1817
+ files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(normalizedAuth) });
1779
1818
  }
1780
1819
  for (const table of Object.values(model.tables)) {
1781
1820
  const typesSrc = emitTypes(table, { dateType: normDateType, numericMode: "string" });
@@ -1790,7 +1829,7 @@ async function generate(configPath) {
1790
1829
  content: emitRoutes(table, graph, {
1791
1830
  softDeleteColumn: cfg.softDeleteColumn || null,
1792
1831
  includeDepthLimit: cfg.includeDepthLimit || 3,
1793
- authStrategy: cfg.auth?.strategy
1832
+ authStrategy: normalizedAuth?.strategy
1794
1833
  })
1795
1834
  });
1796
1835
  files.push({
@@ -1803,8 +1842,8 @@ async function generate(configPath) {
1803
1842
  content: emitClientIndex(Object.values(model.tables))
1804
1843
  });
1805
1844
  files.push({
1806
- path: join(serverDir, "index.ts"),
1807
- content: emitServerIndex(Object.values(model.tables), !!cfg.auth?.strategy && cfg.auth.strategy !== "none")
1845
+ path: join(serverDir, "router.ts"),
1846
+ content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none")
1808
1847
  });
1809
1848
  console.log("✍️ Writing files...");
1810
1849
  await writeFiles(files);
@@ -0,0 +1,5 @@
1
+ import type { Table } from "./introspect";
2
+ /**
3
+ * Emits the server router file that exports helper functions for route registration
4
+ */
5
+ export declare function emitRouter(tables: Table[], hasAuth: boolean): string;
package/dist/index.js CHANGED
@@ -1658,8 +1658,8 @@ export async function authMiddleware(c: Context, next: Next) {
1658
1658
  `;
1659
1659
  }
1660
1660
 
1661
- // src/emit-server-index.ts
1662
- function emitServerIndex(tables, hasAuth) {
1661
+ // src/emit-router.ts
1662
+ function emitRouter(tables, hasAuth) {
1663
1663
  const tableNames = tables.map((t) => t.name).sort();
1664
1664
  const imports = tableNames.map((name) => {
1665
1665
  const Type = pascal(name);
@@ -1687,7 +1687,7 @@ ${hasAuth ? `export { authMiddleware } from "./auth";` : ""}
1687
1687
  * @example
1688
1688
  * import { Hono } from "hono";
1689
1689
  * import { Client } from "pg";
1690
- * import { createRouter } from "./generated/server";
1690
+ * import { createRouter } from "./generated/server/router";
1691
1691
  *
1692
1692
  * const app = new Hono();
1693
1693
  * const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -1715,7 +1715,7 @@ ${registrations}
1715
1715
  * @example
1716
1716
  * import { Hono } from "hono";
1717
1717
  * import { Client } from "pg";
1718
- * import { registerAllRoutes } from "./generated/server";
1718
+ * import { registerAllRoutes } from "./generated/server/router";
1719
1719
  *
1720
1720
  * const app = new Hono();
1721
1721
  * const pg = new Client({ connectionString: process.env.DATABASE_URL });
@@ -1739,11 +1739,50 @@ export * from "./include-spec";
1739
1739
  `;
1740
1740
  }
1741
1741
 
1742
+ // src/types.ts
1743
+ function normalizeAuthConfig(input) {
1744
+ if (!input)
1745
+ return;
1746
+ if ("strategy" in input && input.strategy) {
1747
+ return input;
1748
+ }
1749
+ if ("apiKey" in input && input.apiKey) {
1750
+ return {
1751
+ strategy: "api-key",
1752
+ apiKeyHeader: input.apiKeyHeader,
1753
+ apiKeys: [input.apiKey, ...input.apiKeys || []]
1754
+ };
1755
+ }
1756
+ if ("apiKeys" in input && input.apiKeys?.length) {
1757
+ return {
1758
+ strategy: "api-key",
1759
+ apiKeyHeader: input.apiKeyHeader,
1760
+ apiKeys: input.apiKeys
1761
+ };
1762
+ }
1763
+ if ("jwt" in input && input.jwt) {
1764
+ if (typeof input.jwt === "string") {
1765
+ return {
1766
+ strategy: "jwt-hs256",
1767
+ jwt: { sharedSecret: input.jwt }
1768
+ };
1769
+ } else {
1770
+ return {
1771
+ strategy: "jwt-hs256",
1772
+ jwt: input.jwt
1773
+ };
1774
+ }
1775
+ }
1776
+ return { strategy: "none" };
1777
+ }
1778
+
1742
1779
  // src/index.ts
1743
1780
  async function generate(configPath) {
1744
1781
  const configUrl = pathToFileURL(configPath).href;
1745
1782
  const module = await import(configUrl);
1746
- const cfg = module.default || module;
1783
+ const rawCfg = module.default || module;
1784
+ const normalizedAuth = normalizeAuthConfig(rawCfg.auth);
1785
+ const cfg = { ...rawCfg, auth: normalizedAuth };
1747
1786
  console.log("\uD83D\uDD0D Introspecting database...");
1748
1787
  const model = await introspect(cfg.connectionString, cfg.schema || "public");
1749
1788
  console.log("\uD83D\uDD17 Building relationship graph...");
@@ -1773,8 +1812,8 @@ async function generate(configPath) {
1773
1812
  content: emitIncludeLoader(graph, model, cfg.includeDepthLimit || 3)
1774
1813
  });
1775
1814
  files.push({ path: join(serverDir, "logger.ts"), content: emitLogger() });
1776
- if (cfg.auth?.strategy && cfg.auth.strategy !== "none") {
1777
- files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(cfg.auth) });
1815
+ if (normalizedAuth?.strategy && normalizedAuth.strategy !== "none") {
1816
+ files.push({ path: join(serverDir, "auth.ts"), content: emitAuth(normalizedAuth) });
1778
1817
  }
1779
1818
  for (const table of Object.values(model.tables)) {
1780
1819
  const typesSrc = emitTypes(table, { dateType: normDateType, numericMode: "string" });
@@ -1789,7 +1828,7 @@ async function generate(configPath) {
1789
1828
  content: emitRoutes(table, graph, {
1790
1829
  softDeleteColumn: cfg.softDeleteColumn || null,
1791
1830
  includeDepthLimit: cfg.includeDepthLimit || 3,
1792
- authStrategy: cfg.auth?.strategy
1831
+ authStrategy: normalizedAuth?.strategy
1793
1832
  })
1794
1833
  });
1795
1834
  files.push({
@@ -1802,8 +1841,8 @@ async function generate(configPath) {
1802
1841
  content: emitClientIndex(Object.values(model.tables))
1803
1842
  });
1804
1843
  files.push({
1805
- path: join(serverDir, "index.ts"),
1806
- content: emitServerIndex(Object.values(model.tables), !!cfg.auth?.strategy && cfg.auth.strategy !== "none")
1844
+ path: join(serverDir, "router.ts"),
1845
+ content: emitRouter(Object.values(model.tables), !!normalizedAuth?.strategy && normalizedAuth.strategy !== "none")
1807
1846
  });
1808
1847
  console.log("✍️ Writing files...");
1809
1848
  await writeFiles(files);
package/dist/types.d.ts CHANGED
@@ -8,6 +8,16 @@ export interface AuthConfig {
8
8
  audience?: string;
9
9
  };
10
10
  }
11
+ export type AuthConfigInput = AuthConfig | {
12
+ apiKey?: string;
13
+ apiKeys?: string[];
14
+ apiKeyHeader?: string;
15
+ jwt?: string | {
16
+ sharedSecret?: string;
17
+ issuer?: string;
18
+ audience?: string;
19
+ };
20
+ };
11
21
  export interface Config {
12
22
  connectionString: string;
13
23
  schema?: string;
@@ -16,5 +26,6 @@ export interface Config {
16
26
  softDeleteColumn?: string | null;
17
27
  includeDepthLimit?: number;
18
28
  dateType?: "date" | "string";
19
- auth?: AuthConfig;
29
+ auth?: AuthConfigInput;
20
30
  }
31
+ export declare function normalizeAuthConfig(input: AuthConfigInput | undefined): AuthConfig | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.1.2-alpha.1",
3
+ "version": "0.1.2-alpha.3",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {