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 +32 -0
- package/bin/db_codegen.mjs +14 -7
- package/dist/src/db/codegen_paths.d.ts +6 -0
- package/dist/src/db/codegen_paths.js +19 -1
- package/llms.txt +1 -0
- package/package.json +1 -1
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
|
package/bin/db_codegen.mjs
CHANGED
|
@@ -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
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
110
|
-
|
|
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
|
+
}
|
|
@@ -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
|
|
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
|