cloudflare-next-intl 0.8.9 → 0.8.10

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
@@ -778,6 +778,15 @@ them and fails naming the first one that is stale.
778
778
  npx cfni-db-codegen --out-dir=src/shared/db/generated --out-dir=../other-app/src/db/generated
779
779
  ```
780
780
 
781
+ If no `--db-url`/`CODEGEN_DATABASE_URL` is set and nothing is reachable at the
782
+ local Supabase default, `cfni-db-codegen` falls back to a throwaway,
783
+ local-only Postgres started via the optional `embedded-postgres` package (a
784
+ prebuilt binary, no Docker required): install it once with
785
+ `npm install --save-dev embedded-postgres`, and no local DB setup is needed —
786
+ the DDL in `--ddl-dir` is loaded into it, introspected, and it's torn down
787
+ after. Passing an explicit `--db-url`/`CODEGEN_DATABASE_URL` skips this
788
+ fallback entirely and fails loudly if that target is unreachable.
789
+
781
790
  ##### Keeping `cfni_exec.sql` in sync (`--rpc-dir`/`--rpc-file-name`/`--tests-dir`/`--tests-file-name`/`--force`/`--skip-exec`)
782
791
 
783
792
  After a successful (non-`--check`) run, `cfni-db-codegen` also copies
@@ -37,26 +37,33 @@ import { join, relative } from 'node:path';
37
37
  import { Client } from 'pg';
38
38
  import resolveCodegenPaths from '../dist/src/db/codegen_paths.js';
39
39
  import { runInstallExecStep } from './install_exec_step.mjs';
40
+ import { startEphemeralPostgres } from './ephemeral_pg.mjs';
40
41
 
41
42
  const paths = resolveCodegenPaths(process.argv.slice(2), process.env, process.cwd());
42
43
 
43
- async function assertReachable(url) {
44
+ async function isReachable(url) {
44
45
  const client = new Client({ connectionString: url, connectionTimeoutMillis: paths.timeoutMs });
45
46
  try {
46
47
  await client.connect();
47
48
  await client.end();
48
- } catch (error) {
49
+ return true;
50
+ } catch {
49
51
  await client.end().catch(() => { /* already failed to connect */ });
50
- console.error(`❌ Could not reach Postgres at ${url}\n (${error.message})`);
51
- console.error("\n drizzle-kit pull needs a live Postgres to introspect — any one works, this script has no Docker dependency of its own. Pick one:");
52
- console.error(" - Local Supabase (needs Docker running): ./supabase/scripts/db_start.sh --reset");
53
- console.error(" - A native Postgres you already have: CODEGEN_DATABASE_URL=postgresql://... npm run db:codegen");
54
- console.error(" - A remote/staging database: CODEGEN_DATABASE_URL=postgresql://... npm run db:codegen");
55
- console.error(` Slow/cold-starting target? Raise the timeout: CODEGEN_CONNECT_TIMEOUT_MS=15000 npm run db:codegen`);
56
- process.exit(1);
52
+ return false;
57
53
  }
58
54
  }
59
55
 
56
+ function failUnreachable(url) {
57
+ console.error(`❌ Could not reach Postgres at ${url}`);
58
+ console.error("\n drizzle-kit pull needs a live Postgres to introspect — any one works, this script has no Docker dependency of its own. Pick one:");
59
+ console.error(" - Local Supabase (needs Docker running): ./supabase/scripts/db_start.sh --reset");
60
+ console.error(" - A native Postgres you already have: CODEGEN_DATABASE_URL=postgresql://... npm run db:codegen");
61
+ console.error(" - A remote/staging database: CODEGEN_DATABASE_URL=postgresql://... npm run db:codegen");
62
+ console.error(" - Zero setup (no Docker/Postgres at all): npm install --save-dev embedded-postgres (auto-used as a fallback)");
63
+ console.error(` Slow/cold-starting target? Raise the timeout: CODEGEN_CONNECT_TIMEOUT_MS=15000 npm run db:codegen`);
64
+ process.exit(1);
65
+ }
66
+
60
67
  function sqlFiles(dir) {
61
68
  return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
62
69
  const path = join(dir, entry.name);
@@ -87,10 +94,24 @@ if (paths.check) {
87
94
  process.exit(0);
88
95
  }
89
96
 
90
- await assertReachable(paths.dbUrl);
97
+ let effectiveDbUrl = paths.dbUrl;
98
+ let ephemeral = null;
99
+ if (!(await isReachable(paths.dbUrl))) {
100
+ if (paths.dbUrlExplicit) failUnreachable(paths.dbUrl);
101
+ ephemeral = await startEphemeralPostgres(paths.ephemeralDir, sqlFiles(paths.ddlDir));
102
+ if (!ephemeral) failUnreachable(paths.dbUrl);
103
+ effectiveDbUrl = ephemeral.url;
104
+ }
91
105
 
92
106
  rmSync(paths.pullDir, { recursive: true, force: true });
93
- execFileSync('npx', ['drizzle-kit', 'pull', ...(paths.drizzleConfig ? [`--config=${paths.drizzleConfig}`] : [])], { stdio: 'inherit' });
107
+ try {
108
+ execFileSync('npx', ['drizzle-kit', 'pull', ...(paths.drizzleConfig ? [`--config=${paths.drizzleConfig}`] : [])], {
109
+ stdio: 'inherit',
110
+ env: { ...process.env, CODEGEN_DATABASE_URL: effectiveDbUrl },
111
+ });
112
+ } finally {
113
+ if (ephemeral) await ephemeral.stop();
114
+ }
94
115
 
95
116
  const pulled = join(paths.pullDir, "schema.ts");
96
117
  if (!existsSync(pulled)) {
@@ -0,0 +1,54 @@
1
+ // Spins up a throwaway, local-only Postgres (via `embedded-postgres`, a
2
+ // prebuilt binary — no Docker) so `cfni-db-codegen` can introspect DDL
3
+ // without any live Postgres already running. Used only as a fallback when
4
+ // no --db-url/CODEGEN_DATABASE_URL was given and nothing is reachable at the
5
+ // local Supabase default.
6
+ import { readFileSync, rmSync } from 'node:fs';
7
+ import { Client } from 'pg';
8
+
9
+ const EPHEMERAL_PORT = 54329;
10
+ const EPHEMERAL_URL = `postgresql://postgres:postgres@127.0.0.1:${EPHEMERAL_PORT}/postgres`;
11
+
12
+ /** Starts an ephemeral Postgres, loads every file in `sqlFiles` into it, and
13
+ * returns { url, stop() }. Caller must call stop() when done, even on error. */
14
+ export async function startEphemeralPostgres(dataDir, sqlFiles) {
15
+ let EmbeddedPostgres;
16
+ try {
17
+ ({ default: EmbeddedPostgres } = await import('embedded-postgres'));
18
+ } catch {
19
+ return null; // optional dep not installed — caller falls back to its normal error message
20
+ }
21
+
22
+ rmSync(dataDir, { recursive: true, force: true });
23
+ const pg = new EmbeddedPostgres({
24
+ databaseDir: dataDir,
25
+ port: EPHEMERAL_PORT,
26
+ user: 'postgres',
27
+ password: 'postgres',
28
+ persistent: false,
29
+ });
30
+
31
+ console.log('ℹ️ No reachable Postgres found — starting an ephemeral one (embedded-postgres, no Docker needed)…');
32
+ await pg.initialise();
33
+ await pg.start();
34
+
35
+ const client = new Client({ connectionString: EPHEMERAL_URL });
36
+ await client.connect();
37
+ try {
38
+ for (const file of sqlFiles) {
39
+ const sql = readFileSync(file, 'utf8');
40
+ if (sql.trim().length === 0) continue;
41
+ await client.query(sql);
42
+ }
43
+ } finally {
44
+ await client.end();
45
+ }
46
+
47
+ return {
48
+ url: EPHEMERAL_URL,
49
+ async stop() {
50
+ await pg.stop().catch(() => { /* best-effort */ });
51
+ rmSync(dataDir, { recursive: true, force: true });
52
+ },
53
+ };
54
+ }
@@ -11,6 +11,8 @@ export interface CodegenPaths {
11
11
  pullDir: string;
12
12
  manifest: string;
13
13
  dbUrl: string;
14
+ dbUrlExplicit: boolean;
15
+ ephemeralDir: string;
14
16
  check: boolean;
15
17
  timeoutMs: number;
16
18
  drizzleConfig: string | null;
@@ -52,6 +52,8 @@ export default function resolveCodegenPaths(argv, env, cwd) {
52
52
  pullDir: resolve(outDir, '..', '.drizzle-pull'),
53
53
  manifest: join(outDir, 'manifest.json'),
54
54
  dbUrl: flag(argv, 'db-url') ?? env.CODEGEN_DATABASE_URL ?? DEFAULT_DB_URL,
55
+ dbUrlExplicit: flag(argv, 'db-url') !== undefined || env.CODEGEN_DATABASE_URL !== undefined,
56
+ ephemeralDir: resolve(outDir, '..', '.drizzle-ephemeral-pg'),
55
57
  check: argv.includes('--check'),
56
58
  timeoutMs: Number(env.CODEGEN_CONNECT_TIMEOUT_MS) || DEFAULT_TIMEOUT_MS,
57
59
  drizzleConfig: drizzleConfig === null ? null : abs(cwd, drizzleConfig),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudflare-next-intl",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "description": "Optimized Next Intl Package Special for App Router and Cloudflare",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -243,6 +243,7 @@
243
243
  "@microsoft/clarity": "^1.0.2",
244
244
  "@supabase/supabase-js": "^2.112.3",
245
245
  "drizzle-orm": "^0.45.2",
246
+ "embedded-postgres": "^18.4.0-beta.17",
246
247
  "firebase": "^12.17.0",
247
248
  "jose": "^6.2.8",
248
249
  "pg": "^8.23.0"