spfn 0.2.0-beta.57 → 0.2.0-beta.59

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.
Files changed (3) hide show
  1. package/README.md +9 -0
  2. package/dist/index.js +56 -19
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -69,6 +69,9 @@ already exists). See [Scaffold structure](#scaffold-structure) for what lands on
69
69
  |--------|-------------|
70
70
  | `-y, --yes` | Skip prompts, use defaults |
71
71
 
72
+ Generated projects pin `drizzle-orm` and `drizzle-kit` to `1.0.0-rc.4`, matching
73
+ `@spfn/core` and the rest of the published SPFN database packages.
74
+
72
75
  ### `spfn add <package>`
73
76
 
74
77
  Installs an SPFN ecosystem package and applies its pre-built migrations. The package
@@ -181,6 +184,12 @@ loaded `.env` chain.
181
184
  > `db push` is for development. For production, use `db generate` + `db migrate` to keep
182
185
  > migration history.
183
186
 
187
+ Database TLS is controlled by `DATABASE_URL`. Loopback URLs (`localhost`, `127.0.0.1`,
188
+ and `::1`) default to `ssl: false`; add an explicit `sslmode` when the local server uses
189
+ TLS. For a TLS connection with a self-signed certificate, set
190
+ `SPFN_DB_INSECURE_TLS=1` to disable certificate verification. This opt-in never enables
191
+ TLS by itself and `sslmode=disable` remains authoritative.
192
+
184
193
  ### `spfn env`
185
194
 
186
195
  Schema-driven environment variable tooling (schema comes from a package's `envSchema`,
package/dist/index.js CHANGED
@@ -869,7 +869,7 @@ var init_deployment_config = __esm({
869
869
 
870
870
  // src/utils/version.ts
871
871
  function getCliVersion() {
872
- return "0.2.0-beta.57";
872
+ return "0.2.0-beta.59";
873
873
  }
874
874
  function getTagFromVersion(version) {
875
875
  const match = version.match(/-([a-z]+)\./i);
@@ -896,8 +896,8 @@ async function setupPackageJson(cwd, packageJsonPath, packageJson, packageManage
896
896
  const spfnTag = getSpfnTag();
897
897
  packageJson.dependencies["@spfn/core"] = spfnTag;
898
898
  packageJson.dependencies["@sinclair/typebox"] = "^0.34.0";
899
- packageJson.dependencies["drizzle-orm"] = "^0.45.0";
900
- packageJson.dependencies["drizzle-typebox"] = "^0.1.0";
899
+ packageJson.dependencies["drizzle-orm"] = "1.0.0-rc.4";
900
+ packageJson.dependencies["drizzle-typebox"] = "^0.3.3";
901
901
  packageJson.dependencies["postgres"] = "^3.4.0";
902
902
  packageJson.dependencies["pg"] = "^8.16.3";
903
903
  packageJson.dependencies["spfn"] = spfnTag;
@@ -908,7 +908,7 @@ async function setupPackageJson(cwd, packageJsonPath, packageJson, packageManage
908
908
  packageJson.devDependencies["@types/node"] = "^20.11.0";
909
909
  packageJson.devDependencies["tsx"] = "^4.20.6";
910
910
  packageJson.devDependencies["tsup"] = "^8.5.0";
911
- packageJson.devDependencies["drizzle-kit"] = "^0.31.5";
911
+ packageJson.devDependencies["drizzle-kit"] = "1.0.0-rc.4";
912
912
  packageJson.devDependencies["dotenv"] = "^17.2.3";
913
913
  if (!packageJson.scripts["build"]) {
914
914
  packageJson.scripts["build"] = "next build --turbopack";
@@ -2770,19 +2770,56 @@ import chalk10 from "chalk";
2770
2770
  import ora6 from "ora";
2771
2771
  import { env } from "@spfn/core/config";
2772
2772
  import { loadEnv } from "@spfn/core/server";
2773
- function shouldRelaxDbTls(databaseUrl) {
2774
- if (process.env.SPFN_DB_INSECURE_TLS === "1" || process.env.SPFN_DB_INSECURE_TLS === "true") {
2775
- return true;
2776
- }
2773
+ var TLS_SSL_MODES = /* @__PURE__ */ new Set(["no-verify", "prefer", "require", "verify-ca", "verify-full"]);
2774
+ function parseDatabaseUrl(databaseUrl) {
2777
2775
  if (!databaseUrl) {
2778
- return false;
2776
+ return void 0;
2779
2777
  }
2780
2778
  try {
2781
- const host = new URL(databaseUrl).hostname.replace(/^\[|\]$/g, "");
2782
- return host === "localhost" || host === "127.0.0.1" || host === "::1";
2779
+ return new URL(databaseUrl);
2783
2780
  } catch {
2784
- return false;
2781
+ return void 0;
2782
+ }
2783
+ }
2784
+ function isLoopbackDatabaseUrl(databaseUrl) {
2785
+ const host = databaseUrl.hostname.replace(/^\[|\]$/g, "");
2786
+ return host === "localhost" || host === "127.0.0.1" || host === "::1";
2787
+ }
2788
+ function requestsDbTls(databaseUrl) {
2789
+ const sslMode = databaseUrl.searchParams.get("sslmode")?.toLowerCase();
2790
+ if (sslMode) {
2791
+ return TLS_SSL_MODES.has(sslMode);
2792
+ }
2793
+ return databaseUrl.searchParams.get("ssl")?.toLowerCase() === "true";
2794
+ }
2795
+ function insecureDbTlsEnabled() {
2796
+ return process.env.SPFN_DB_INSECURE_TLS === "1" || process.env.SPFN_DB_INSECURE_TLS === "true";
2797
+ }
2798
+ function shouldRelaxDbTls(databaseUrl) {
2799
+ const parsedUrl = parseDatabaseUrl(databaseUrl);
2800
+ const sslMode = parsedUrl?.searchParams.get("sslmode")?.toLowerCase();
2801
+ return insecureDbTlsEnabled() && parsedUrl !== void 0 && requestsDbTls(parsedUrl) && sslMode !== "no-verify";
2802
+ }
2803
+ function resolvePushConnectionConfig(databaseUrl) {
2804
+ const parsedUrl = parseDatabaseUrl(databaseUrl);
2805
+ if (!parsedUrl) {
2806
+ return { connectionString: databaseUrl };
2807
+ }
2808
+ const sslMode = parsedUrl.searchParams.get("sslmode")?.toLowerCase();
2809
+ const hasExplicitSslSetting = parsedUrl.searchParams.has("sslmode") || parsedUrl.searchParams.has("ssl");
2810
+ if (sslMode === "disable") {
2811
+ return { connectionString: databaseUrl, ssl: false };
2812
+ }
2813
+ const tlsRequested = requestsDbTls(parsedUrl);
2814
+ if (!hasExplicitSslSetting && isLoopbackDatabaseUrl(parsedUrl)) {
2815
+ return { connectionString: databaseUrl, ssl: false };
2816
+ }
2817
+ if (!tlsRequested || !insecureDbTlsEnabled()) {
2818
+ return { connectionString: databaseUrl };
2785
2819
  }
2820
+ parsedUrl.searchParams.set("sslmode", "no-verify");
2821
+ parsedUrl.searchParams.delete("ssl");
2822
+ return { connectionString: parsedUrl.toString() };
2786
2823
  }
2787
2824
  function validateDatabasePrerequisites() {
2788
2825
  loadEnv();
@@ -2881,10 +2918,10 @@ async function createPushConnection() {
2881
2918
  }
2882
2919
  const pg = await import("pg");
2883
2920
  const { drizzle } = await import("drizzle-orm/node-postgres");
2921
+ const connectionConfig = resolvePushConnectionConfig(env.DATABASE_URL);
2884
2922
  const pool = new pg.default.Pool({
2885
- connectionString: env.DATABASE_URL,
2886
- max: 1,
2887
- ...shouldRelaxDbTls(env.DATABASE_URL) ? { ssl: { rejectUnauthorized: false } } : {}
2923
+ ...connectionConfig,
2924
+ max: 1
2888
2925
  });
2889
2926
  const db = drizzle({ client: pool });
2890
2927
  return {
@@ -3148,7 +3185,7 @@ import ora7 from "ora";
3148
3185
  import net from "net";
3149
3186
  import chalk15 from "chalk";
3150
3187
  import prompts4 from "prompts";
3151
- function parseDatabaseUrl(dbUrl) {
3188
+ function parseDatabaseUrl2(dbUrl) {
3152
3189
  try {
3153
3190
  const url = new URL(dbUrl);
3154
3191
  return {
@@ -3400,7 +3437,7 @@ async function dbBackup(options) {
3400
3437
  console.log(chalk18.yellow("\n\u{1F4A1} Tip: Add DATABASE_URL to your .env file"));
3401
3438
  process.exit(1);
3402
3439
  }
3403
- const dbInfo = parseDatabaseUrl(dbUrl);
3440
+ const dbInfo = parseDatabaseUrl2(dbUrl);
3404
3441
  const backupDir = await ensureBackupDir();
3405
3442
  const timestamp = formatTimestamp();
3406
3443
  const format = options.format || "sql";
@@ -3660,7 +3697,7 @@ async function dbDrop() {
3660
3697
  console.log(chalk21.yellow("\n\u{1F4A1} Tip: Add DATABASE_URL to your .env file"));
3661
3698
  process.exit(1);
3662
3699
  }
3663
- const dbInfo = parseDatabaseUrl(env6.DATABASE_URL);
3700
+ const dbInfo = parseDatabaseUrl2(env6.DATABASE_URL);
3664
3701
  console.log(chalk21.yellow("\u26A0\uFE0F WARNING: This will drop all tables in your database!"));
3665
3702
  console.log(chalk21.dim(` Target: ${dbInfo.database} @ ${dbInfo.host}:${dbInfo.port}
3666
3703
  `));
@@ -3784,7 +3821,7 @@ async function dbRestore(backupFile, options = {}) {
3784
3821
  console.log("");
3785
3822
  }
3786
3823
  }
3787
- const dbInfo = parseDatabaseUrl(dbUrl);
3824
+ const dbInfo = parseDatabaseUrl2(dbUrl);
3788
3825
  const { confirm } = await prompts6({
3789
3826
  type: "confirm",
3790
3827
  name: "confirm",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spfn",
3
- "version": "0.2.0-beta.57",
3
+ "version": "0.2.0-beta.59",
4
4
  "description": "Superfunction CLI - Add SPFN to your Next.js project",
5
5
  "type": "module",
6
6
  "bin": {