cloudflare-next-intl 0.8.4 → 0.8.5

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
@@ -558,6 +558,38 @@ re-export of `drizzle-orm`'s common query-building primitives (`eq`, `and`,
558
558
  `drizzle-orm` directly — this package re-exports the query-operator surface
559
559
  only, not the whole library.
560
560
 
561
+ #### Schema codegen (`cfni-db-codegen`)
562
+
563
+ The package ships a `cfni-db-codegen` binary that regenerates Drizzle models by
564
+ introspecting a live Postgres with `drizzle-kit pull`, patches drizzle-kit's
565
+ bare function-call defaults into raw-SQL-wrapped ones, and writes a
566
+ `manifest.json` next to the schema so `--check` can fail CI when the DDL
567
+ changed without regenerating.
568
+
569
+ ```bash
570
+ npx cfni-db-codegen
571
+ npx cfni-db-codegen --check
572
+ ```
573
+
574
+ | Flag | Env | Default |
575
+ | --- | --- | --- |
576
+ | `--ddl-dir=` | `CFNI_DB_DDL_DIR` | `supabase/data-base` |
577
+ | `--out-dir=` | `CFNI_DB_OUT_DIR` | `src/shared/db/generated` |
578
+ | `--out-file=` | `CFNI_DB_OUT_FILE` | `schema.ts` |
579
+ | `--db-url=` | `CODEGEN_DATABASE_URL` | `postgresql://postgres:postgres@127.0.0.1:54322/postgres` |
580
+ | `--drizzle-config=` | `CFNI_DB_DRIZZLE_CONFIG` | none |
581
+ | `--check` | — | off |
582
+
583
+ `--out-dir` may be repeated, or given a comma-separated list, to generate the
584
+ same schema into several projects in one run (`CFNI_DB_OUT_DIR` accepts a
585
+ comma-separated list too). The database is introspected once and the identical
586
+ schema plus manifest is written to every target; `--check` verifies all of
587
+ them and fails naming the first one that is stale.
588
+
589
+ ```bash
590
+ npx cfni-db-codegen --out-dir=src/shared/db/generated --out-dir=../other-app/src/db/generated
591
+ ```
592
+
561
593
  #### Testing code that calls `withPublicDb`/`withUserDb`
562
594
 
563
595
  `cloudflare-next-intl/dbTesting` exports a fake `DrizzleDb` so repository/unit
@@ -2,6 +2,10 @@
2
2
  // Regenerates Drizzle models by introspecting a live Postgres with drizzle-kit.
3
3
  // Usage: cfni-db-codegen [--check] [--ddl-dir=…] [--out-dir=…] [--out-file=…] [--db-url=…] [--drizzle-config=…]
4
4
  //
5
+ // --out-dir may be repeated, or given a comma-separated list, to generate the
6
+ // same schema into several projects at once (CFNI_DB_OUT_DIR accepts a
7
+ // comma-separated list too).
8
+ //
5
9
  // Needs a reachable Postgres to introspect — any Postgres, not specifically
6
10
  // a Docker one. Set CODEGEN_DATABASE_URL to point at whichever you have:
7
11
  // local Supabase (./supabase/scripts/db_start.sh --reset, needs Docker), a
@@ -55,9 +59,10 @@ function ddlHash() {
55
59
  const hash = ddlHash();
56
60
 
57
61
  if (paths.check) {
58
- const previous = existsSync(paths.manifest) ? JSON.parse(readFileSync(paths.manifest, "utf8")).ddlHash : null;
59
- if (previous !== hash) {
60
- console.error(`❌ ${relative(process.cwd(), paths.ddlDir)} changed without regenerating models. Run: npm run db:codegen`);
62
+ for (const target of paths.targets) {
63
+ const previous = existsSync(target.manifest) ? JSON.parse(readFileSync(target.manifest, "utf8")).ddlHash : null;
64
+ if (previous === hash) continue;
65
+ console.error(`❌ ${relative(process.cwd(), paths.ddlDir)} changed without regenerating models in ${relative(process.cwd(), target.outDir)}. Run: npm run db:codegen`);
61
66
  process.exit(1);
62
67
  }
63
68
  console.log(`✅ Drizzle models are in sync with ${relative(process.cwd(), paths.ddlDir)}`);
@@ -69,7 +74,6 @@ await assertReachable(paths.dbUrl);
69
74
  rmSync(paths.pullDir, { recursive: true, force: true });
70
75
  execFileSync('npx', ['drizzle-kit', 'pull', ...(paths.drizzleConfig ? [`--config=${paths.drizzleConfig}`] : [])], { stdio: 'inherit' });
71
76
 
72
- mkdirSync(paths.outDir, { recursive: true });
73
77
  const pulled = join(paths.pullDir, "schema.ts");
74
78
  if (!existsSync(pulled)) {
75
79
  console.error(`❌ drizzle-kit pull produced no schema at ${pulled}`);
@@ -104,7 +108,10 @@ function patchBareFunctionCallDefaults(source) {
104
108
 
105
109
  const banner = `// GENERATED by cfni-db-codegen from ${relative(process.cwd(), paths.ddlDir)} — do not edit.\n`;
106
110
  const pulledSource = patchBareFunctionCallDefaults(readFileSync(pulled, "utf8"));
107
- writeFileSync(paths.outFile, banner + pulledSource);
108
111
  rmSync(paths.pullDir, { recursive: true, force: true });
109
- writeFileSync(paths.manifest, `${JSON.stringify({ ddlHash: hash }, null, 2)}\n`);
110
- console.log(`✅ Generated ${relative(process.cwd(), paths.outFile)}`);
112
+ for (const target of paths.targets) {
113
+ mkdirSync(target.outDir, { recursive: true });
114
+ writeFileSync(target.outFile, banner + pulledSource);
115
+ writeFileSync(target.manifest, `${JSON.stringify({ ddlHash: hash }, null, 2)}\n`);
116
+ console.log(`✅ Generated ${relative(process.cwd(), target.outFile)}`);
117
+ }
@@ -1,5 +1,11 @@
1
+ export interface CodegenTarget {
2
+ outDir: string;
3
+ outFile: string;
4
+ manifest: string;
5
+ }
1
6
  export interface CodegenPaths {
2
7
  ddlDir: string;
8
+ targets: CodegenTarget[];
3
9
  outDir: string;
4
10
  outFile: string;
5
11
  pullDir: string;
@@ -4,6 +4,13 @@ const DEFAULT_OUT_DIR = 'src/shared/db/generated';
4
4
  const DEFAULT_OUT_FILE = 'schema.ts';
5
5
  const DEFAULT_DB_URL = 'postgresql://postgres:postgres@127.0.0.1:54322/postgres';
6
6
  const DEFAULT_TIMEOUT_MS = 5000;
7
+ function flags(argv, name) {
8
+ const prefix = `--${name}=`;
9
+ return argv.filter((arg) => arg.startsWith(prefix)).map((arg) => arg.slice(prefix.length));
10
+ }
11
+ function list(value) {
12
+ return value.split(',').map((part) => part.trim()).filter(Boolean);
13
+ }
7
14
  function flag(argv, name) {
8
15
  const prefix = `--${name}=`;
9
16
  const hit = argv.find((arg) => arg.startsWith(prefix));
@@ -15,11 +22,22 @@ function abs(cwd, value) {
15
22
  /** Resolves every codegen path from flags, then env, then the documented defaults. */
16
23
  export default function resolveCodegenPaths(argv, env, cwd) {
17
24
  const ddlDir = abs(cwd, flag(argv, 'ddl-dir') ?? env.CFNI_DB_DDL_DIR ?? DEFAULT_DDL_DIR);
18
- const outDir = abs(cwd, flag(argv, 'out-dir') ?? env.CFNI_DB_OUT_DIR ?? DEFAULT_OUT_DIR);
25
+ const outDirArgs = flags(argv, 'out-dir').flatMap(list);
26
+ const outDirs = (outDirArgs.length > 0
27
+ ? outDirArgs
28
+ : list(env.CFNI_DB_OUT_DIR ?? '')).map((dir) => abs(cwd, dir));
29
+ if (outDirs.length === 0)
30
+ outDirs.push(abs(cwd, DEFAULT_OUT_DIR));
31
+ const outDir = outDirs[0];
19
32
  const outFileName = flag(argv, 'out-file') ?? env.CFNI_DB_OUT_FILE ?? DEFAULT_OUT_FILE;
20
33
  const drizzleConfig = flag(argv, 'drizzle-config') ?? env.CFNI_DB_DRIZZLE_CONFIG ?? null;
21
34
  return {
22
35
  ddlDir,
36
+ targets: outDirs.map((dir) => ({
37
+ outDir: dir,
38
+ outFile: join(dir, outFileName),
39
+ manifest: join(dir, 'manifest.json'),
40
+ })),
23
41
  outDir,
24
42
  outFile: join(outDir, outFileName),
25
43
  pullDir: resolve(outDir, '..', '.drizzle-pull'),
package/llms.txt CHANGED
@@ -60,6 +60,7 @@ Two transports, picked by which `db` fields are set — `pg`/`drizzle-orm`/`@sup
60
60
  - `withPublicDb(fn)` — anonymous role. Direct-Postgres mode: the request's pooled connection, no transaction, no role switch. Supabase mode: the anon key as the PostgREST bearer token. Either way, no user id is attached — RLS keyed on `auth.jwt()` denies access.
61
61
  - `withUserDb(fn, uid?)` — signed-in-user role. Direct-Postgres mode: a transaction with `set_config('request.jwt.claims', ...)` + `set local role`, `uid` resolution order explicit arg → `db.getUserId()` → Firebase auth uid → throws. Supabase mode: identity rides on the JWT from `db.getAccessToken`/Firebase instead (`uid` param is ignored), no transaction wraps the call.
62
62
  - `./dbHelpers` functions are plain Drizzle `sql`-building utilities with no config dependency — usable standalone.
63
+ - `cfni-db-codegen` binary — regenerates Drizzle models via `drizzle-kit pull`. Flags/env: `--ddl-dir`/`CFNI_DB_DDL_DIR`, `--out-dir`/`CFNI_DB_OUT_DIR`, `--out-file`/`CFNI_DB_OUT_FILE`, `--db-url`/`CODEGEN_DATABASE_URL`, `--drizzle-config`/`CFNI_DB_DRIZZLE_CONFIG`, `--check`. `--out-dir` is repeatable and accepts a comma-separated list, so one run generates the same schema (and `manifest.json`) into several projects; `--check` verifies every target.
63
64
 
64
65
  ```typescript
65
66
  // src/i18n/intl_config.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudflare-next-intl",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
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",