@beignet/cli 0.0.8 → 0.0.9
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/CHANGELOG.md +11 -0
- package/README.md +50 -65
- package/dist/create.js +1 -1
- package/dist/create.js.map +1 -1
- package/dist/inspect.js +78 -12
- package/dist/inspect.js.map +1 -1
- package/dist/make.js +2 -2
- package/dist/templates/base.js +4 -4
- package/dist/templates/base.js.map +1 -1
- package/dist/templates/db.js +16 -16
- package/dist/templates/server.js +10 -10
- package/dist/templates/server.js.map +1 -1
- package/package.json +2 -2
- package/src/create.ts +1 -1
- package/src/inspect.ts +137 -19
- package/src/make.ts +2 -2
- package/src/templates/base.ts +4 -4
- package/src/templates/db.ts +16 -16
- package/src/templates/server.ts +10 -10
package/dist/make.js
CHANGED
|
@@ -3865,7 +3865,7 @@ function drizzleRepositoryFile(names, config, mode, options) {
|
|
|
3865
3865
|
].filter((name) => Boolean(name));
|
|
3866
3866
|
return `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
3867
3867
|
import { cursorPageResult } from "@beignet/core/pagination";
|
|
3868
|
-
import type {
|
|
3868
|
+
import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
3869
3869
|
import { ${drizzleImports.join(", ")} } from "drizzle-orm";
|
|
3870
3870
|
import type { ${names.singularPascal}Repository } from "${aliasModule(repositoryPortPath)}";
|
|
3871
3871
|
import { encode${names.singularPascal}Cursor } from "${aliasModule(resourceSchemaFilePath(names, config))}";
|
|
@@ -3945,7 +3945,7 @@ function cursorFor${names.singularPascal}(
|
|
|
3945
3945
|
}
|
|
3946
3946
|
|
|
3947
3947
|
export function createDrizzle${names.singularPascal}Repository(
|
|
3948
|
-
db:
|
|
3948
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
3949
3949
|
): ${names.singularPascal}Repository {
|
|
3950
3950
|
return {
|
|
3951
3951
|
async list(query) {
|
package/dist/templates/base.js
CHANGED
|
@@ -7,7 +7,7 @@ export function packageJson(ctx) {
|
|
|
7
7
|
"@beignet/devtools": ctx.beignetVersion,
|
|
8
8
|
"@beignet/next": ctx.beignetVersion,
|
|
9
9
|
"@beignet/provider-auth-better-auth": ctx.beignetVersion,
|
|
10
|
-
"@beignet/provider-drizzle
|
|
10
|
+
"@beignet/provider-db-drizzle": ctx.beignetVersion,
|
|
11
11
|
"@beignet/provider-logger-pino": ctx.beignetVersion,
|
|
12
12
|
"@libsql/client": externalVersions.libsqlClient,
|
|
13
13
|
"better-auth": externalVersions.betterAuth,
|
|
@@ -185,7 +185,7 @@ ${cli} doctor
|
|
|
185
185
|
${shellMap}
|
|
186
186
|
## Before deploying
|
|
187
187
|
|
|
188
|
-
-
|
|
188
|
+
- Keep \`SQLITE_DB_URL=file:local.db\` for local libSQL development or point it at a hosted libSQL database such as Turso.
|
|
189
189
|
- Run \`${cli} db generate\` and \`${cli} db migrate\` after changing the Drizzle schema.
|
|
190
190
|
- Run \`${cli} db reset\` to rebuild a local SQLite database from the checked-in migrations.
|
|
191
191
|
- Remove \`DEVTOOLS_ENABLED=true\` in production unless you add authentication and stricter redaction.
|
|
@@ -227,8 +227,8 @@ export function envExample(ctx) {
|
|
|
227
227
|
`LOG_SERVICE=${ctx.name}`,
|
|
228
228
|
"",
|
|
229
229
|
"# Use file:local.db for local libSQL or libsql://... for Turso cloud.",
|
|
230
|
-
"
|
|
231
|
-
"#
|
|
230
|
+
"SQLITE_DB_URL=file:local.db",
|
|
231
|
+
"# SQLITE_DB_AUTH_TOKEN=",
|
|
232
232
|
"",
|
|
233
233
|
"BETTER_AUTH_SECRET=local-dev-better-auth-secret-change-me",
|
|
234
234
|
"BETTER_AUTH_URL=http://localhost:3000",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/templates/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,IAAI,EACJ,aAAa,GAEd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,UAAU,WAAW,CAAC,GAAoB;IAC9C,MAAM,YAAY,GAA2B;QAC3C,eAAe,EAAE,GAAG,CAAC,cAAc;QACnC,mBAAmB,EAAE,GAAG,CAAC,cAAc;QACvC,eAAe,EAAE,GAAG,CAAC,cAAc;QACnC,oCAAoC,EAAE,GAAG,CAAC,cAAc;QACxD,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/templates/base.ts"],"names":[],"mappings":"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"}
|
package/dist/templates/db.js
CHANGED
|
@@ -14,8 +14,8 @@ const files = {
|
|
|
14
14
|
out: "./drizzle",
|
|
15
15
|
dialect: "sqlite",
|
|
16
16
|
dbCredentials: {
|
|
17
|
-
url: process.env.
|
|
18
|
-
authToken: process.env.
|
|
17
|
+
url: process.env.SQLITE_DB_URL ?? "file:local.db",
|
|
18
|
+
authToken: process.env.SQLITE_DB_AUTH_TOKEN,
|
|
19
19
|
},
|
|
20
20
|
};
|
|
21
21
|
`,
|
|
@@ -122,7 +122,7 @@ export const idempotencyRecords = sqliteTable(
|
|
|
122
122
|
`,
|
|
123
123
|
drizzleTodoRepository: `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
124
124
|
import { offsetPageResult } from "@beignet/core/pagination";
|
|
125
|
-
import type {
|
|
125
|
+
import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
126
126
|
import { count, desc, eq } from "drizzle-orm";
|
|
127
127
|
import type {
|
|
128
128
|
NewTodo,
|
|
@@ -145,7 +145,7 @@ function toTodo(row: TodoRow): Todo {
|
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
export function createDrizzleTodoRepository(
|
|
148
|
-
db:
|
|
148
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
149
149
|
): TodoRepository {
|
|
150
150
|
return {
|
|
151
151
|
async list(userId, page) {
|
|
@@ -207,13 +207,13 @@ export function createDrizzleTodoRepository(
|
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
209
|
`,
|
|
210
|
-
dbRepositories: `import type {
|
|
210
|
+
dbRepositories: `import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
211
211
|
import { createDrizzleTodoRepository } from "@/infra/todos/drizzle-todo-repository";
|
|
212
212
|
import type { AppTransactionPorts } from "@/ports";
|
|
213
213
|
import * as schema from "./schema";
|
|
214
214
|
|
|
215
215
|
export function createRepositories(
|
|
216
|
-
db:
|
|
216
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
217
217
|
): Omit<AppTransactionPorts, "idempotency"> {
|
|
218
218
|
return {
|
|
219
219
|
todos: createDrizzleTodoRepository(db),
|
|
@@ -264,10 +264,10 @@ async function prepare(client: Client): Promise<void> {
|
|
|
264
264
|
dbProvider: `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
265
265
|
import { createProvider } from "@beignet/core/providers";
|
|
266
266
|
import {
|
|
267
|
-
|
|
268
|
-
|
|
267
|
+
createDrizzleSqliteIdempotencyPort,
|
|
268
|
+
createDrizzleSqliteUnitOfWork,
|
|
269
269
|
type DbPort,
|
|
270
|
-
} from "@beignet/provider-drizzle
|
|
270
|
+
} from "@beignet/provider-db-drizzle/sqlite";
|
|
271
271
|
import type { AppPorts } from "@/ports";
|
|
272
272
|
import { ensureDatabaseReady } from "./database-ready";
|
|
273
273
|
import { createRepositories } from "./repositories";
|
|
@@ -282,21 +282,21 @@ export const starterDatabaseProvider = createProvider<{
|
|
|
282
282
|
const dbPort = ports.db;
|
|
283
283
|
if (!dbPort) {
|
|
284
284
|
throw new Error(
|
|
285
|
-
"starterDatabaseProvider requires a db port. Register
|
|
285
|
+
"starterDatabaseProvider requires a db port. Register createDrizzleSqliteProvider({ schema }) before it.",
|
|
286
286
|
);
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
const repositories = createRepositories(dbPort.db);
|
|
290
|
-
const idempotency =
|
|
290
|
+
const idempotency = createDrizzleSqliteIdempotencyPort(dbPort.db);
|
|
291
291
|
|
|
292
292
|
const providedPorts: Pick<AppPorts, "idempotency" | "todos" | "uow"> = {
|
|
293
293
|
...repositories,
|
|
294
294
|
idempotency,
|
|
295
|
-
uow:
|
|
295
|
+
uow: createDrizzleSqliteUnitOfWork({
|
|
296
296
|
db: dbPort.db,
|
|
297
297
|
createTransactionPorts: (tx) => ({
|
|
298
298
|
...createRepositories(tx),
|
|
299
|
-
idempotency:
|
|
299
|
+
idempotency: createDrizzleSqliteIdempotencyPort(tx),
|
|
300
300
|
}),
|
|
301
301
|
}),
|
|
302
302
|
};
|
|
@@ -316,7 +316,7 @@ import { migrate } from "drizzle-orm/libsql/migrator";
|
|
|
316
316
|
import { env } from "@/lib/env";
|
|
317
317
|
|
|
318
318
|
if (
|
|
319
|
-
!env.
|
|
319
|
+
!env.SQLITE_DB_URL.startsWith("file:") &&
|
|
320
320
|
process.env.BEIGNET_ALLOW_DATABASE_RESET !== "true"
|
|
321
321
|
) {
|
|
322
322
|
throw new Error(
|
|
@@ -335,8 +335,8 @@ const tables = [
|
|
|
335
335
|
] as const;
|
|
336
336
|
|
|
337
337
|
const client = createClient({
|
|
338
|
-
url: env.
|
|
339
|
-
authToken: env.
|
|
338
|
+
url: env.SQLITE_DB_URL,
|
|
339
|
+
authToken: env.SQLITE_DB_AUTH_TOKEN,
|
|
340
340
|
});
|
|
341
341
|
|
|
342
342
|
try {
|
package/dist/templates/server.js
CHANGED
|
@@ -4,7 +4,7 @@ export function serverProviders(ctx) {
|
|
|
4
4
|
'import type { beignetServerOnly } from "@beignet/core/server-only";',
|
|
5
5
|
'import { createDevtoolsProvider } from "@beignet/devtools";',
|
|
6
6
|
'import { createAuthBetterAuthProvider } from "@beignet/provider-auth-better-auth";',
|
|
7
|
-
'import {
|
|
7
|
+
'import { createDrizzleSqliteProvider } from "@beignet/provider-db-drizzle/sqlite";',
|
|
8
8
|
hasIntegration(ctx, "inngest")
|
|
9
9
|
? 'import { inngestProvider } from "@beignet/provider-inngest";'
|
|
10
10
|
: undefined,
|
|
@@ -24,7 +24,7 @@ export function serverProviders(ctx) {
|
|
|
24
24
|
"\tcreateDevtoolsProvider(),",
|
|
25
25
|
"\tcreateAuthBetterAuthProvider<AuthUser, AuthSessionMetadata>(auth),",
|
|
26
26
|
"\tloggerPinoProvider,",
|
|
27
|
-
"\
|
|
27
|
+
"\tdrizzleSqliteProvider,",
|
|
28
28
|
"\tstarterDatabaseProvider,",
|
|
29
29
|
hasIntegration(ctx, "inngest") ? "\tinngestProvider," : undefined,
|
|
30
30
|
hasIntegration(ctx, "resend") ? "\tmailResendProvider," : undefined,
|
|
@@ -34,7 +34,7 @@ export function serverProviders(ctx) {
|
|
|
34
34
|
].filter((entry) => Boolean(entry));
|
|
35
35
|
return `${imports.join("\n")}
|
|
36
36
|
|
|
37
|
-
const
|
|
37
|
+
const drizzleSqliteProvider = createDrizzleSqliteProvider({ schema });
|
|
38
38
|
|
|
39
39
|
export const providers = [
|
|
40
40
|
${entries.join("\n")}
|
|
@@ -143,8 +143,8 @@ export const env = createEnv({
|
|
|
143
143
|
.default("local-dev-better-auth-secret-change-me"),
|
|
144
144
|
BETTER_AUTH_URL: z.string().url().default("http://localhost:3000"),
|
|
145
145
|
BETTER_AUTH_TRUSTED_ORIGINS: z.string().optional(),
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
SQLITE_DB_URL: z.string().default("file:local.db"),
|
|
147
|
+
SQLITE_DB_AUTH_TOKEN: z.string().optional(),
|
|
148
148
|
LOG_LEVEL: z
|
|
149
149
|
.enum(["trace", "debug", "info", "warn", "error", "fatal"])
|
|
150
150
|
.default("info"),
|
|
@@ -336,9 +336,9 @@ export const server = await createNextServer({
|
|
|
336
336
|
ports: appPorts,
|
|
337
337
|
providers,
|
|
338
338
|
providerConfig: {
|
|
339
|
-
"drizzle-
|
|
340
|
-
DB_URL: env.
|
|
341
|
-
DB_AUTH_TOKEN: env.
|
|
339
|
+
"drizzle-sqlite": {
|
|
340
|
+
DB_URL: env.SQLITE_DB_URL,
|
|
341
|
+
DB_AUTH_TOKEN: env.SQLITE_DB_AUTH_TOKEN,
|
|
342
342
|
},
|
|
343
343
|
},
|
|
344
344
|
hooks: [createIdempotencyHooks<AppContext>()],
|
|
@@ -420,8 +420,8 @@ import * as schema from "@/infra/db/schema";
|
|
|
420
420
|
import { env } from "@/lib/env";
|
|
421
421
|
|
|
422
422
|
const client = createClient({
|
|
423
|
-
url: env.
|
|
424
|
-
authToken: env.
|
|
423
|
+
url: env.SQLITE_DB_URL,
|
|
424
|
+
authToken: env.SQLITE_DB_AUTH_TOKEN,
|
|
425
425
|
});
|
|
426
426
|
|
|
427
427
|
// Auth routes can be the first thing to touch the database, before any
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/templates/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAwB,MAAM,aAAa,CAAC;AAEnE,MAAM,UAAU,eAAe,CAAC,GAAoB;IAClD,MAAM,OAAO,GAAG;QACd,qEAAqE;QACrE,6DAA6D;QAC7D,oFAAoF;QACpF
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/templates/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beignet/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for creating and maintaining Beignet apps.",
|
|
6
6
|
"main": "./dist/lib.js",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"typescript": "^5.3.0"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@beignet/core": "^0.0.
|
|
69
|
+
"@beignet/core": "^0.0.9",
|
|
70
70
|
"@clack/prompts": "^1.5.1",
|
|
71
71
|
"@stricli/core": "^1.2.7",
|
|
72
72
|
"jiti": "^2.7.0"
|
package/src/create.ts
CHANGED
|
@@ -95,7 +95,7 @@ export async function createProject(
|
|
|
95
95
|
* Providers that ship in every starter. They used to be `--integrations`
|
|
96
96
|
* choices, so passing them gets a pointed error instead of a generic one.
|
|
97
97
|
*/
|
|
98
|
-
const baseProviderNames = new Set(["better-auth", "drizzle-
|
|
98
|
+
const baseProviderNames = new Set(["better-auth", "drizzle-sqlite", "pino"]);
|
|
99
99
|
|
|
100
100
|
function resolveIntegrations(
|
|
101
101
|
explicitIntegrations: IntegrationName[],
|
package/src/inspect.ts
CHANGED
|
@@ -1865,6 +1865,14 @@ async function inspectRouteErrorCatalogDrift(
|
|
|
1865
1865
|
return diagnostics;
|
|
1866
1866
|
}
|
|
1867
1867
|
|
|
1868
|
+
type ProviderDoctorVariantRule = {
|
|
1869
|
+
name: string;
|
|
1870
|
+
displayName: string;
|
|
1871
|
+
tokens: readonly string[];
|
|
1872
|
+
requiredEnv: readonly string[];
|
|
1873
|
+
registrationSeverity?: "warning" | "hint";
|
|
1874
|
+
};
|
|
1875
|
+
|
|
1868
1876
|
type ProviderDoctorRule = {
|
|
1869
1877
|
packageName: string;
|
|
1870
1878
|
displayName: string;
|
|
@@ -1872,6 +1880,7 @@ type ProviderDoctorRule = {
|
|
|
1872
1880
|
appPorts?: readonly { name: string; type: string }[];
|
|
1873
1881
|
requiredEnv?: readonly string[];
|
|
1874
1882
|
registrationSeverity?: "warning" | "hint";
|
|
1883
|
+
variants?: readonly ProviderDoctorVariantRule[];
|
|
1875
1884
|
};
|
|
1876
1885
|
|
|
1877
1886
|
type ProviderPackageMetadataSource = {
|
|
@@ -1960,8 +1969,40 @@ async function inspectProductionReadiness(
|
|
|
1960
1969
|
}
|
|
1961
1970
|
}
|
|
1962
1971
|
|
|
1972
|
+
const providerEntries = await readProviderListEntries(
|
|
1973
|
+
targetDir,
|
|
1974
|
+
files,
|
|
1975
|
+
config,
|
|
1976
|
+
sourceCache,
|
|
1977
|
+
);
|
|
1978
|
+
|
|
1963
1979
|
for (const provider of providerDoctorRules) {
|
|
1964
1980
|
if (!installedPackages.has(provider.packageName)) continue;
|
|
1981
|
+
|
|
1982
|
+
if (provider.variants !== undefined) {
|
|
1983
|
+
// Multi-variant packages only require the env vars of the variants the
|
|
1984
|
+
// app actually registers; an unused variant must not warn.
|
|
1985
|
+
for (const variant of detectedProviderVariants(
|
|
1986
|
+
provider.variants,
|
|
1987
|
+
providerEntries,
|
|
1988
|
+
)) {
|
|
1989
|
+
for (const envVar of variant.requiredEnv) {
|
|
1990
|
+
if (
|
|
1991
|
+
await anyFileContains(targetDir, configFiles, envVar, sourceCache)
|
|
1992
|
+
) {
|
|
1993
|
+
continue;
|
|
1994
|
+
}
|
|
1995
|
+
diagnostics.push({
|
|
1996
|
+
severity: "warning",
|
|
1997
|
+
code: "BEIGNET_PROVIDER_ENV_MISSING",
|
|
1998
|
+
file: "package.json",
|
|
1999
|
+
message: `${provider.packageName} is installed and ${variant.displayName} is registered, but ${envVar} is not mentioned in app env/config files. ${variant.displayName} requires ${envVar}; add the environment variable or remove the provider registration.`,
|
|
2000
|
+
});
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
continue;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
1965
2006
|
for (const envVar of provider.requiredEnv ?? []) {
|
|
1966
2007
|
if (await anyFileContains(targetDir, configFiles, envVar, sourceCache)) {
|
|
1967
2008
|
continue;
|
|
@@ -2153,23 +2194,38 @@ async function inspectProviderRegistrationDrift(
|
|
|
2153
2194
|
);
|
|
2154
2195
|
const providerFiles = serverProviderFiles(files, config);
|
|
2155
2196
|
const sourceCache = new Map<string, string>();
|
|
2156
|
-
const
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
).join("\n");
|
|
2163
|
-
const providerListSource = extractProviderListSource(providerSource);
|
|
2164
|
-
const providerEntries =
|
|
2165
|
-
providerListSource === undefined
|
|
2166
|
-
? []
|
|
2167
|
-
: providerListEntries(providerListSource);
|
|
2197
|
+
const providerEntries = await readProviderListEntries(
|
|
2198
|
+
targetDir,
|
|
2199
|
+
files,
|
|
2200
|
+
config,
|
|
2201
|
+
sourceCache,
|
|
2202
|
+
);
|
|
2168
2203
|
|
|
2169
2204
|
for (const provider of providerDoctorRules) {
|
|
2205
|
+
if (!installedPackages.has(provider.packageName)) continue;
|
|
2206
|
+
|
|
2207
|
+
if (provider.variants !== undefined) {
|
|
2208
|
+
if (
|
|
2209
|
+
detectedProviderVariants(provider.variants, providerEntries).length > 0
|
|
2210
|
+
) {
|
|
2211
|
+
continue;
|
|
2212
|
+
}
|
|
2213
|
+
const severity = providerVariantRegistrationSeverity(provider.variants);
|
|
2214
|
+
if (severity === undefined) continue;
|
|
2215
|
+
const hints = provider.variants
|
|
2216
|
+
.filter((variant) => variant.tokens.length > 0)
|
|
2217
|
+
.map((variant) => registrationTokenHint(variant.tokens));
|
|
2218
|
+
diagnostics.push({
|
|
2219
|
+
severity,
|
|
2220
|
+
code: "BEIGNET_PROVIDER_REGISTRATION_MISSING",
|
|
2221
|
+
file: providerFiles[0] ?? config.paths.server,
|
|
2222
|
+
message: `${provider.packageName} is installed, but no ${provider.displayName} variant is registered in server/providers.ts. Register one of the available providers (${hints.join(", ")}) in the exported providers array or remove the unused package.`,
|
|
2223
|
+
});
|
|
2224
|
+
continue;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2170
2227
|
const severity = provider.registrationSeverity;
|
|
2171
2228
|
if (severity === undefined) continue;
|
|
2172
|
-
if (!installedPackages.has(provider.packageName)) continue;
|
|
2173
2229
|
if (
|
|
2174
2230
|
provider.tokens.some((token) =>
|
|
2175
2231
|
providerEntries.some((entry) => entry.includes(token)),
|
|
@@ -2190,8 +2246,12 @@ async function inspectProviderRegistrationDrift(
|
|
|
2190
2246
|
}
|
|
2191
2247
|
|
|
2192
2248
|
const drizzleIndex = findProviderEntryIndex(providerEntries, [
|
|
2193
|
-
"
|
|
2194
|
-
"
|
|
2249
|
+
"drizzleSqliteProvider",
|
|
2250
|
+
"createDrizzleSqliteProvider",
|
|
2251
|
+
"drizzlePostgresProvider",
|
|
2252
|
+
"createDrizzlePostgresProvider",
|
|
2253
|
+
"drizzleMysqlProvider",
|
|
2254
|
+
"createDrizzleMysqlProvider",
|
|
2195
2255
|
]);
|
|
2196
2256
|
const appDatabaseProviderIndex = findProviderEntryIndex(providerEntries, [
|
|
2197
2257
|
"starterDatabaseProvider",
|
|
@@ -2209,7 +2269,7 @@ async function inspectProviderRegistrationDrift(
|
|
|
2209
2269
|
code: "BEIGNET_PROVIDER_ORDER",
|
|
2210
2270
|
file: providerFiles[0] ?? config.paths.server,
|
|
2211
2271
|
message:
|
|
2212
|
-
"An app database provider is registered before
|
|
2272
|
+
"An app database provider is registered before the Drizzle database provider. Register the Drizzle database provider first so app-owned database wiring can read ctx.ports.db during setup.",
|
|
2213
2273
|
});
|
|
2214
2274
|
}
|
|
2215
2275
|
|
|
@@ -2361,12 +2421,70 @@ function providerDoctorRuleFromMetadata(
|
|
|
2361
2421
|
tokens: registration?.tokens ?? [],
|
|
2362
2422
|
appPorts: metadata.appPorts ?? [],
|
|
2363
2423
|
requiredEnv: metadata.requiredEnv ?? [],
|
|
2364
|
-
registrationSeverity:
|
|
2365
|
-
|
|
2366
|
-
|
|
2424
|
+
registrationSeverity: registrationSeverityFromMetadata(registration),
|
|
2425
|
+
variants: metadata.variants?.map((variant) => ({
|
|
2426
|
+
name: variant.name,
|
|
2427
|
+
displayName: variant.displayName ?? variant.name,
|
|
2428
|
+
tokens: variant.registration?.tokens ?? [],
|
|
2429
|
+
requiredEnv: variant.requiredEnv ?? [],
|
|
2430
|
+
registrationSeverity: registrationSeverityFromMetadata(
|
|
2431
|
+
variant.registration,
|
|
2432
|
+
),
|
|
2433
|
+
})),
|
|
2367
2434
|
};
|
|
2368
2435
|
}
|
|
2369
2436
|
|
|
2437
|
+
function registrationSeverityFromMetadata(
|
|
2438
|
+
registration:
|
|
2439
|
+
| { required?: boolean; severity?: "warning" | "hint" }
|
|
2440
|
+
| undefined,
|
|
2441
|
+
): "warning" | "hint" | undefined {
|
|
2442
|
+
return (
|
|
2443
|
+
registration?.severity ??
|
|
2444
|
+
(registration?.required === true ? "warning" : undefined)
|
|
2445
|
+
);
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
function detectedProviderVariants(
|
|
2449
|
+
variants: readonly ProviderDoctorVariantRule[],
|
|
2450
|
+
providerEntries: readonly string[],
|
|
2451
|
+
): ProviderDoctorVariantRule[] {
|
|
2452
|
+
return variants.filter((variant) =>
|
|
2453
|
+
variant.tokens.some((token) =>
|
|
2454
|
+
providerEntries.some((entry) => entry.includes(token)),
|
|
2455
|
+
),
|
|
2456
|
+
);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
function providerVariantRegistrationSeverity(
|
|
2460
|
+
variants: readonly ProviderDoctorVariantRule[],
|
|
2461
|
+
): "warning" | "hint" | undefined {
|
|
2462
|
+
const severities = variants.map((variant) => variant.registrationSeverity);
|
|
2463
|
+
if (severities.includes("warning")) return "warning";
|
|
2464
|
+
if (severities.includes("hint")) return "hint";
|
|
2465
|
+
return undefined;
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
async function readProviderListEntries(
|
|
2469
|
+
targetDir: string,
|
|
2470
|
+
files: string[],
|
|
2471
|
+
config: ResolvedBeignetConfig,
|
|
2472
|
+
sourceCache: Map<string, string>,
|
|
2473
|
+
): Promise<string[]> {
|
|
2474
|
+
const providerFiles = serverProviderFiles(files, config);
|
|
2475
|
+
const providerSource = (
|
|
2476
|
+
await Promise.all(
|
|
2477
|
+
providerFiles.map((file) =>
|
|
2478
|
+
readCachedSource(targetDir, file, sourceCache),
|
|
2479
|
+
),
|
|
2480
|
+
)
|
|
2481
|
+
).join("\n");
|
|
2482
|
+
const providerListSource = extractProviderListSource(providerSource);
|
|
2483
|
+
return providerListSource === undefined
|
|
2484
|
+
? []
|
|
2485
|
+
: providerListEntries(providerListSource);
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2370
2488
|
function registrationTokenHint(tokens: readonly string[]): string {
|
|
2371
2489
|
const token = tokens[0];
|
|
2372
2490
|
if (!token) return "the provider";
|
package/src/make.ts
CHANGED
|
@@ -5898,7 +5898,7 @@ function drizzleRepositoryFile(
|
|
|
5898
5898
|
|
|
5899
5899
|
return `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
5900
5900
|
import { cursorPageResult } from "@beignet/core/pagination";
|
|
5901
|
-
import type {
|
|
5901
|
+
import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
5902
5902
|
import { ${drizzleImports.join(", ")} } from "drizzle-orm";
|
|
5903
5903
|
import type { ${names.singularPascal}Repository } from "${aliasModule(repositoryPortPath)}";
|
|
5904
5904
|
import { encode${names.singularPascal}Cursor } from "${aliasModule(resourceSchemaFilePath(names, config))}";
|
|
@@ -5978,7 +5978,7 @@ function cursorFor${names.singularPascal}(
|
|
|
5978
5978
|
}
|
|
5979
5979
|
|
|
5980
5980
|
export function createDrizzle${names.singularPascal}Repository(
|
|
5981
|
-
db:
|
|
5981
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
5982
5982
|
): ${names.singularPascal}Repository {
|
|
5983
5983
|
return {
|
|
5984
5984
|
async list(query) {
|
package/src/templates/base.ts
CHANGED
|
@@ -15,7 +15,7 @@ export function packageJson(ctx: TemplateContext): string {
|
|
|
15
15
|
"@beignet/devtools": ctx.beignetVersion,
|
|
16
16
|
"@beignet/next": ctx.beignetVersion,
|
|
17
17
|
"@beignet/provider-auth-better-auth": ctx.beignetVersion,
|
|
18
|
-
"@beignet/provider-drizzle
|
|
18
|
+
"@beignet/provider-db-drizzle": ctx.beignetVersion,
|
|
19
19
|
"@beignet/provider-logger-pino": ctx.beignetVersion,
|
|
20
20
|
"@libsql/client": externalVersions.libsqlClient,
|
|
21
21
|
"better-auth": externalVersions.betterAuth,
|
|
@@ -214,7 +214,7 @@ ${cli} doctor
|
|
|
214
214
|
${shellMap}
|
|
215
215
|
## Before deploying
|
|
216
216
|
|
|
217
|
-
-
|
|
217
|
+
- Keep \`SQLITE_DB_URL=file:local.db\` for local libSQL development or point it at a hosted libSQL database such as Turso.
|
|
218
218
|
- Run \`${cli} db generate\` and \`${cli} db migrate\` after changing the Drizzle schema.
|
|
219
219
|
- Run \`${cli} db reset\` to rebuild a local SQLite database from the checked-in migrations.
|
|
220
220
|
- Remove \`DEVTOOLS_ENABLED=true\` in production unless you add authentication and stricter redaction.
|
|
@@ -288,8 +288,8 @@ export function envExample(ctx: TemplateContext): string {
|
|
|
288
288
|
`LOG_SERVICE=${ctx.name}`,
|
|
289
289
|
"",
|
|
290
290
|
"# Use file:local.db for local libSQL or libsql://... for Turso cloud.",
|
|
291
|
-
"
|
|
292
|
-
"#
|
|
291
|
+
"SQLITE_DB_URL=file:local.db",
|
|
292
|
+
"# SQLITE_DB_AUTH_TOKEN=",
|
|
293
293
|
"",
|
|
294
294
|
"BETTER_AUTH_SECRET=local-dev-better-auth-secret-change-me",
|
|
295
295
|
"BETTER_AUTH_URL=http://localhost:3000",
|
package/src/templates/db.ts
CHANGED
|
@@ -15,8 +15,8 @@ const files = {
|
|
|
15
15
|
out: "./drizzle",
|
|
16
16
|
dialect: "sqlite",
|
|
17
17
|
dbCredentials: {
|
|
18
|
-
url: process.env.
|
|
19
|
-
authToken: process.env.
|
|
18
|
+
url: process.env.SQLITE_DB_URL ?? "file:local.db",
|
|
19
|
+
authToken: process.env.SQLITE_DB_AUTH_TOKEN,
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
`,
|
|
@@ -123,7 +123,7 @@ export const idempotencyRecords = sqliteTable(
|
|
|
123
123
|
`,
|
|
124
124
|
drizzleTodoRepository: `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
125
125
|
import { offsetPageResult } from "@beignet/core/pagination";
|
|
126
|
-
import type {
|
|
126
|
+
import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
127
127
|
import { count, desc, eq } from "drizzle-orm";
|
|
128
128
|
import type {
|
|
129
129
|
NewTodo,
|
|
@@ -146,7 +146,7 @@ function toTodo(row: TodoRow): Todo {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
export function createDrizzleTodoRepository(
|
|
149
|
-
db:
|
|
149
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
150
150
|
): TodoRepository {
|
|
151
151
|
return {
|
|
152
152
|
async list(userId, page) {
|
|
@@ -208,13 +208,13 @@ export function createDrizzleTodoRepository(
|
|
|
208
208
|
};
|
|
209
209
|
}
|
|
210
210
|
`,
|
|
211
|
-
dbRepositories: `import type {
|
|
211
|
+
dbRepositories: `import type { DrizzleSqliteDatabase } from "@beignet/provider-db-drizzle/sqlite";
|
|
212
212
|
import { createDrizzleTodoRepository } from "@/infra/todos/drizzle-todo-repository";
|
|
213
213
|
import type { AppTransactionPorts } from "@/ports";
|
|
214
214
|
import * as schema from "./schema";
|
|
215
215
|
|
|
216
216
|
export function createRepositories(
|
|
217
|
-
db:
|
|
217
|
+
db: DrizzleSqliteDatabase<typeof schema>,
|
|
218
218
|
): Omit<AppTransactionPorts, "idempotency"> {
|
|
219
219
|
return {
|
|
220
220
|
todos: createDrizzleTodoRepository(db),
|
|
@@ -265,10 +265,10 @@ async function prepare(client: Client): Promise<void> {
|
|
|
265
265
|
dbProvider: `import type { beignetServerOnly } from "@beignet/core/server-only";
|
|
266
266
|
import { createProvider } from "@beignet/core/providers";
|
|
267
267
|
import {
|
|
268
|
-
|
|
269
|
-
|
|
268
|
+
createDrizzleSqliteIdempotencyPort,
|
|
269
|
+
createDrizzleSqliteUnitOfWork,
|
|
270
270
|
type DbPort,
|
|
271
|
-
} from "@beignet/provider-drizzle
|
|
271
|
+
} from "@beignet/provider-db-drizzle/sqlite";
|
|
272
272
|
import type { AppPorts } from "@/ports";
|
|
273
273
|
import { ensureDatabaseReady } from "./database-ready";
|
|
274
274
|
import { createRepositories } from "./repositories";
|
|
@@ -283,21 +283,21 @@ export const starterDatabaseProvider = createProvider<{
|
|
|
283
283
|
const dbPort = ports.db;
|
|
284
284
|
if (!dbPort) {
|
|
285
285
|
throw new Error(
|
|
286
|
-
"starterDatabaseProvider requires a db port. Register
|
|
286
|
+
"starterDatabaseProvider requires a db port. Register createDrizzleSqliteProvider({ schema }) before it.",
|
|
287
287
|
);
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
const repositories = createRepositories(dbPort.db);
|
|
291
|
-
const idempotency =
|
|
291
|
+
const idempotency = createDrizzleSqliteIdempotencyPort(dbPort.db);
|
|
292
292
|
|
|
293
293
|
const providedPorts: Pick<AppPorts, "idempotency" | "todos" | "uow"> = {
|
|
294
294
|
...repositories,
|
|
295
295
|
idempotency,
|
|
296
|
-
uow:
|
|
296
|
+
uow: createDrizzleSqliteUnitOfWork({
|
|
297
297
|
db: dbPort.db,
|
|
298
298
|
createTransactionPorts: (tx) => ({
|
|
299
299
|
...createRepositories(tx),
|
|
300
|
-
idempotency:
|
|
300
|
+
idempotency: createDrizzleSqliteIdempotencyPort(tx),
|
|
301
301
|
}),
|
|
302
302
|
}),
|
|
303
303
|
};
|
|
@@ -317,7 +317,7 @@ import { migrate } from "drizzle-orm/libsql/migrator";
|
|
|
317
317
|
import { env } from "@/lib/env";
|
|
318
318
|
|
|
319
319
|
if (
|
|
320
|
-
!env.
|
|
320
|
+
!env.SQLITE_DB_URL.startsWith("file:") &&
|
|
321
321
|
process.env.BEIGNET_ALLOW_DATABASE_RESET !== "true"
|
|
322
322
|
) {
|
|
323
323
|
throw new Error(
|
|
@@ -336,8 +336,8 @@ const tables = [
|
|
|
336
336
|
] as const;
|
|
337
337
|
|
|
338
338
|
const client = createClient({
|
|
339
|
-
url: env.
|
|
340
|
-
authToken: env.
|
|
339
|
+
url: env.SQLITE_DB_URL,
|
|
340
|
+
authToken: env.SQLITE_DB_AUTH_TOKEN,
|
|
341
341
|
});
|
|
342
342
|
|
|
343
343
|
try {
|