postgresdk 0.16.7 → 0.16.8

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 CHANGED
@@ -1805,6 +1805,15 @@ function extractConfigFields(configContent) {
1805
1805
  isCommented: pullBlock.isCommented
1806
1806
  });
1807
1807
  }
1808
+ const pullTokenMatch = configContent.match(/^\s*(\/\/)?\s*pullToken:\s*(.+),?$/m);
1809
+ if (pullTokenMatch) {
1810
+ fields.push({
1811
+ key: "pullToken",
1812
+ value: pullTokenMatch[2]?.trim().replace(/,$/, ""),
1813
+ description: "Token for protecting /_psdk/* endpoints",
1814
+ isCommented: !!pullTokenMatch[1]
1815
+ });
1816
+ }
1808
1817
  return fields;
1809
1818
  }
1810
1819
  function extractComplexBlock(configContent, blockName) {
@@ -1947,21 +1956,36 @@ export default {
1947
1956
  ${getComplexBlockLine("tests", existingFields, mergeStrategy, userChoices)}
1948
1957
 
1949
1958
  // ========== AUTHENTICATION ==========
1950
-
1959
+
1951
1960
  /**
1952
1961
  * Authentication configuration for your API
1953
- *
1962
+ *
1954
1963
  * Simple syntax examples:
1955
1964
  * auth: { apiKey: process.env.API_KEY }
1956
1965
  * auth: { jwt: process.env.JWT_SECRET }
1957
- *
1966
+ *
1958
1967
  * Multiple API keys:
1959
1968
  * auth: { apiKeys: [process.env.KEY1, process.env.KEY2] }
1960
- *
1969
+ *
1961
1970
  * Full syntax for advanced options:
1962
1971
  */
1963
1972
  ${getComplexBlockLine("auth", existingFields, mergeStrategy, userChoices)}
1964
-
1973
+
1974
+ // ========== SDK ENDPOINT PROTECTION ==========
1975
+
1976
+ /**
1977
+ * Token for protecting /_psdk/* endpoints (SDK distribution and contract endpoints)
1978
+ *
1979
+ * When set, clients must provide this token via Authorization header when pulling SDK.
1980
+ * If not set, /_psdk/* endpoints are publicly accessible.
1981
+ *
1982
+ * This is separate from the main auth strategy (JWT/API key) used for CRUD operations.
1983
+ *
1984
+ * Use "env:" prefix to read from environment variables:
1985
+ * pullToken: "env:POSTGRESDK_PULL_TOKEN"
1986
+ */
1987
+ ${getFieldLine("pullToken", existingFields, mergeStrategy, '"env:POSTGRESDK_PULL_TOKEN"', userChoices)}
1988
+
1965
1989
  // ========== SDK DISTRIBUTION (Pull Configuration) ==========
1966
1990
 
1967
1991
  /**
@@ -2050,9 +2074,9 @@ function getDefaultComplexBlock(key) {
2050
2074
  // },`;
2051
2075
  case "pull":
2052
2076
  return `// pull: {
2053
- // from: "https://api.myapp.com", // API URL to pull SDK from
2054
- // output: "./src/sdk", // Local directory for pulled SDK
2055
- // token: process.env.API_TOKEN, // Optional authentication token
2077
+ // from: "https://api.myapp.com", // API URL to pull SDK from
2078
+ // output: "./src/sdk", // Local directory for pulled SDK
2079
+ // pullToken: "env:POSTGRESDK_PULL_TOKEN", // Optional: if server has pullToken set
2056
2080
  // },`;
2057
2081
  default:
2058
2082
  return `// ${key}: {},`;
@@ -2154,6 +2178,7 @@ async function initCommand(args) {
2154
2178
  const newOptions = [
2155
2179
  { key: "tests", description: "Enable test generation" },
2156
2180
  { key: "auth", description: "Add authentication" },
2181
+ { key: "pullToken", description: "Add SDK endpoint protection" },
2157
2182
  { key: "pull", description: "Configure SDK distribution" }
2158
2183
  ];
2159
2184
  const existingKeys = new Set(existingFields.map((f) => f.key));
@@ -2518,7 +2543,14 @@ Options:`);
2518
2543
  const headers = resolvedToken ? { Authorization: `Bearer ${resolvedToken}` } : {};
2519
2544
  const manifestRes = await fetch(`${config.from}/_psdk/sdk/manifest`, { headers });
2520
2545
  if (!manifestRes.ok) {
2521
- throw new Error(`Failed to fetch SDK manifest: ${manifestRes.status} ${manifestRes.statusText}`);
2546
+ let errorMsg = `${manifestRes.status} ${manifestRes.statusText}`;
2547
+ try {
2548
+ const errorBody = await manifestRes.json();
2549
+ if (errorBody.error) {
2550
+ errorMsg = errorBody.error;
2551
+ }
2552
+ } catch {}
2553
+ throw new Error(`Failed to fetch SDK manifest: ${errorMsg}`);
2522
2554
  }
2523
2555
  const manifest = await manifestRes.json();
2524
2556
  console.log(`\uD83D\uDCE6 SDK version: ${manifest.version}`);
@@ -2526,7 +2558,14 @@ Options:`);
2526
2558
  console.log(`\uD83D\uDCC4 Files: ${manifest.files.length}`);
2527
2559
  const sdkRes = await fetch(`${config.from}/_psdk/sdk/download`, { headers });
2528
2560
  if (!sdkRes.ok) {
2529
- throw new Error(`Failed to download SDK: ${sdkRes.status} ${sdkRes.statusText}`);
2561
+ let errorMsg = `${sdkRes.status} ${sdkRes.statusText}`;
2562
+ try {
2563
+ const errorBody = await sdkRes.json();
2564
+ if (errorBody.error) {
2565
+ errorMsg = errorBody.error;
2566
+ }
2567
+ } catch {}
2568
+ throw new Error(`Failed to download SDK: ${errorMsg}`);
2530
2569
  }
2531
2570
  const sdk = await sdkRes.json();
2532
2571
  for (const [path, content] of Object.entries(sdk.files)) {
@@ -4481,10 +4520,12 @@ function emitHonoRouter(tables, hasAuth, useJsExtensions, pullToken) {
4481
4520
  const tableNames = tables.map((t) => t.name).sort();
4482
4521
  const ext = useJsExtensions ? ".js" : "";
4483
4522
  let resolvedPullToken;
4523
+ let pullTokenEnvVar;
4484
4524
  if (pullToken) {
4485
4525
  if (pullToken.startsWith("env:")) {
4486
4526
  const envVarName = pullToken.slice(4);
4487
4527
  resolvedPullToken = `process.env.${envVarName}`;
4528
+ pullTokenEnvVar = envVarName;
4488
4529
  } else {
4489
4530
  resolvedPullToken = JSON.stringify(pullToken);
4490
4531
  }
@@ -4586,7 +4627,9 @@ ${pullToken ? `
4586
4627
 
4587
4628
  if (!expectedToken) {
4588
4629
  // Token not configured in environment - reject request
4589
- return c.json({ error: "SDK endpoints are protected but token not configured" }, 500);
4630
+ return c.json({
4631
+ error: "SDK endpoints are protected but pullToken environment variable not set. ${pullTokenEnvVar ? `Set ${pullTokenEnvVar} in your environment or remove pullToken from config.` : "Set the pullToken environment variable or remove pullToken from config."}"
4632
+ }, 500);
4590
4633
  }
4591
4634
 
4592
4635
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
package/dist/index.js CHANGED
@@ -3619,10 +3619,12 @@ function emitHonoRouter(tables, hasAuth, useJsExtensions, pullToken) {
3619
3619
  const tableNames = tables.map((t) => t.name).sort();
3620
3620
  const ext = useJsExtensions ? ".js" : "";
3621
3621
  let resolvedPullToken;
3622
+ let pullTokenEnvVar;
3622
3623
  if (pullToken) {
3623
3624
  if (pullToken.startsWith("env:")) {
3624
3625
  const envVarName = pullToken.slice(4);
3625
3626
  resolvedPullToken = `process.env.${envVarName}`;
3627
+ pullTokenEnvVar = envVarName;
3626
3628
  } else {
3627
3629
  resolvedPullToken = JSON.stringify(pullToken);
3628
3630
  }
@@ -3724,7 +3726,9 @@ ${pullToken ? `
3724
3726
 
3725
3727
  if (!expectedToken) {
3726
3728
  // Token not configured in environment - reject request
3727
- return c.json({ error: "SDK endpoints are protected but token not configured" }, 500);
3729
+ return c.json({
3730
+ error: "SDK endpoints are protected but pullToken environment variable not set. ${pullTokenEnvVar ? `Set ${pullTokenEnvVar} in your environment or remove pullToken from config.` : "Set the pullToken environment variable or remove pullToken from config."}"
3731
+ }, 500);
3728
3732
  }
3729
3733
 
3730
3734
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "postgresdk",
3
- "version": "0.16.7",
3
+ "version": "0.16.8",
4
4
  "description": "Generate a typed server/client SDK from a Postgres schema (includes, Zod, Hono).",
5
5
  "type": "module",
6
6
  "bin": {