@coreframe/db 0.1.3 → 0.1.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/dist/client.d.ts CHANGED
@@ -12,19 +12,23 @@ type DatabaseClient = {
12
12
  transaction?<Result>(run: (database: DatabaseClient) => Promise<Result>): Promise<Result>;
13
13
  close?(): Promise<void>;
14
14
  };
15
- type DrizzleExecutor = {
16
- execute<Result = unknown>(query: SQL): Result | Promise<Result>;
15
+ type PostgresDrizzleExecutor = {
16
+ execute(query: SQL): PromiseLike<unknown>;
17
17
  };
18
+ type SqliteDrizzleExecutor = {
19
+ all(query: SQL): PromiseLike<unknown[]>;
20
+ };
21
+ type DrizzleExecutor = PostgresDrizzleExecutor;
18
22
  type CreateDatabaseAdapterOptions = {
19
- close?(): Promise<void>;
20
- database: DrizzleExecutor;
21
- dialect: DatabaseDialect;
23
+ database: PostgresDrizzleExecutor;
24
+ dialect: "postgres";
25
+ close?: () => Promise<void>;
26
+ } | {
27
+ database: SqliteDrizzleExecutor;
28
+ dialect: "sqlite";
29
+ close?: () => Promise<void>;
22
30
  };
23
- declare function createDatabaseAdapter({
24
- close,
25
- database,
26
- dialect
27
- }: CreateDatabaseAdapterOptions): DatabaseClient;
31
+ declare function createDatabaseAdapter(options: CreateDatabaseAdapterOptions): DatabaseClient;
28
32
  declare function normalizeQueryResult<Row extends Record<string, unknown> = Record<string, unknown>>(result: unknown): QueryResult<Row>;
29
33
  //#endregion
30
- export { CreateDatabaseAdapterOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, QueryResult, createDatabaseAdapter, normalizeQueryResult };
34
+ export { CreateDatabaseAdapterOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, PostgresDrizzleExecutor, QueryResult, SqliteDrizzleExecutor, createDatabaseAdapter, normalizeQueryResult };
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import{sql as e}from"drizzle-orm";function t({close:t,database:r,dialect:i}){return{dialect:i,async execute(t){return n(await r.execute(e.raw(t)))},close:t}}function n(e){return Array.isArray(e)?{rows:e}:r(e)?{rowCount:typeof e.rowCount==`number`?e.rowCount:null,rows:e.rows}:{rows:[]}}function r(e){return typeof e==`object`&&!!e&&`rows`in e&&Array.isArray(e.rows)}export{t as createDatabaseAdapter,n as normalizeQueryResult};
1
+ import{sql as e}from"drizzle-orm";function t(t){return{dialect:t.dialect,async execute(r){let i=e.raw(r);return t.dialect===`sqlite`?n(await t.database.all(i)):n(await t.database.execute(i))},close:t.close}}function n(e){return Array.isArray(e)?{rows:e}:r(e)?{rowCount:typeof e.rowCount==`number`?e.rowCount:null,rows:e.rows}:{rows:[]}}function r(e){return typeof e==`object`&&!!e&&`rows`in e&&Array.isArray(e.rows)}export{t as createDatabaseAdapter,n as normalizeQueryResult};
@@ -1,9 +1,11 @@
1
1
  //#region src/drizzle-kit.d.ts
2
2
  type DrizzleKitCommand = "generate" | "migrate" | "studio";
3
3
  type RunDrizzleKitCommandOptions = {
4
+ cwd?: string;
4
5
  env?: NodeJS.ProcessEnv;
5
6
  };
6
7
  declare function runDrizzleKitCommand(command: DrizzleKitCommand, args?: string[], {
8
+ cwd,
7
9
  env
8
10
  }?: RunDrizzleKitCommandOptions): Promise<void>;
9
11
  //#endregion
@@ -1 +1 @@
1
- import{startProjectPostgres as e}from"./local-postgres.js";import t from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import n from"node:path";import r from"node:process";import{readProjectConfig as i}from"@coreframe/config";import a from"nano-spawn";const o=n.resolve(`node_modules`,`.bin`),s=r.platform===`win32`?`drizzle-kit.cmd`:`drizzle-kit`;async function c(n,a=[],{env:o=r.env}={}){try{var s=t();if((await i()).database?.dialect===`sqlite`){let e=o.TURSO_DATABASE_URL??o.DATABASE_URL;if(!e)throw Error(`TURSO_DATABASE_URL or DATABASE_URL is required for SQLite Drizzle commands.`);await l(a,n,{...o,DATABASE_URL:e});return}await l(a,n,s.a(await e({env:o,useSupervisorLease:!0})).env)}catch(e){s.e=e}finally{await s.d()}}async function l(e,t,r){let i=r.PATH??r.Path??``;await a(s,[t,...e],{env:{...r,PATH:o+n.delimiter+i},stdio:`inherit`})}export{c as runDrizzleKitCommand};
1
+ import{startProjectPostgres as e}from"./local-postgres.js";import{startProjectTurso as t}from"./local-turso.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import r from"node:path";import i from"node:process";import{readProjectConfig as a}from"@coreframe/config";import o from"nano-spawn";const s=i.platform===`win32`?`drizzle-kit.cmd`:`drizzle-kit`;async function c(r,o=[],{cwd:s=i.cwd(),env:c=i.env}={}){try{var u=n();let i=await a({cwd:s});if(i.database?.dialect===`sqlite`)try{var d=n();await l(o,r,s,d.a(await t({config:i,cwd:s,env:c,useSupervisorLease:!0})).env);return}catch(e){d.e=e}finally{await d.d()}await l(o,r,s,u.a(await e({config:i,cwd:s,env:c,useSupervisorLease:!0})).env)}catch(e){u.e=e}finally{await u.d()}}async function l(e,t,n,i){let a=i.PATH??i.Path??``;await o(s,[t,...e],{cwd:n,env:{...i,PATH:r.resolve(n,`node_modules`,`.bin`)+r.delimiter+a},stdio:`inherit`})}export{c as runDrizzleKitCommand};
package/dist/ensure.d.ts CHANGED
@@ -1,8 +1,14 @@
1
+ import { CoreframeConfig } from "@coreframe/config";
2
+
1
3
  //#region src/ensure.d.ts
2
4
  type EnsureLocalDbOptions = {
5
+ config?: CoreframeConfig;
6
+ cwd?: string;
3
7
  env?: NodeJS.ProcessEnv;
4
8
  };
5
9
  declare function ensureLocalDb({
10
+ config,
11
+ cwd,
6
12
  env
7
13
  }?: EnsureLocalDbOptions): Promise<void>;
8
14
  //#endregion
package/dist/ensure.js CHANGED
@@ -1 +1 @@
1
- import{SEED_EMAILS as e,SEED_IDS as t}from"./config.js";import{createLocalPostgresDb as n,startProjectPostgres as r}from"./local-postgres.js";import i from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as a,planLocalSchemaPush as o}from"./schema-push.js";import{seedLocalDb as s}from"./seed.js";import{setupLocalDb as c}from"./setup.js";import{eq as l}from"drizzle-orm";import{importProjectModule as u}from"@coreframe/config";async function d(){return{schema:await u(`src/db/schema.ts`)}}async function f(n,{users:r}){let[i]=await n.select({id:r.id}).from(r).where(l(r.email,e.adminUser)).limit(1);return i?.id===t.adminUser}async function p(e,{schema:t}){let n=await o(a(t),t,e);return n.sqlStatements.length===0?(console.log(`Local database schema already in sync`),{appliedStatements:0,plan:n}):(console.log(`Local database schema drift detected; applying ${n.sqlStatements.length} statement(s)`),await n.apply(),console.log(`Local database schema synced`),{appliedStatements:n.sqlStatements.length,plan:n})}async function m({env:e=process.env}={}){try{var t=i();let a=t.a(await r({env:e,useSupervisorLease:!0})).env,o=await d(),l=await n({env:a});try{if(await h(l,o.schema))console.log(`Local database already set up`);else{console.log(`Local database is missing or unseeded; running setup`),await c(`default`,{env:a});return}(await p(l,o)).appliedStatements>0&&!await h(l,o.schema)&&(console.log(`Local database seed data missing after schema sync; running seed`),await s(void 0,{env:a}))}finally{await l.$client.end()}}catch(e){t.e=e}finally{await t.d()}}async function h(e,t){try{return await f(e,t)}catch{return!1}}export{m as ensureLocalDb};
1
+ import{SEED_EMAILS as e,SEED_IDS as t}from"./config.js";import{createProjectSqliteDrizzleDatabase as n}from"./project.js";import{createLocalPostgresDb as r,startProjectPostgres as i}from"./local-postgres.js";import{startProjectTurso as a}from"./local-turso.js";import o from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{migrateLocalDb as s}from"./migrate.js";import{setupLocalDb as c}from"./setup.js";import{eq as l}from"drizzle-orm";import{importProjectModule as u,readProjectConfig as d}from"@coreframe/config";async function f(e){return{schema:await u(`src/db/schema.ts`,e)}}async function p(n,{users:r}){let[i]=await n.select({id:r.id}).from(r).where(l(r.email,e.adminUser)).limit(1);return i?.id===t.adminUser}async function m({config:e,cwd:t=process.cwd(),env:s=process.env}={}){try{var c=o();let u=e??await d({cwd:t}),p=await f(t);if(u.database?.dialect===`sqlite`)try{var l=o();let e=l.a(await a({config:u,cwd:t,env:s,useSupervisorLease:!0}));await h({config:u,cwd:t,db:await n({cwd:t,env:e.env}),env:e.env,modules:p});return}catch(e){l.e=e}finally{await l.d()}let m=c.a(await i({config:u,cwd:t,env:s,useSupervisorLease:!0}));await h({config:u,cwd:t,db:await r({cwd:t,env:m.env}),env:m.env,modules:p})}catch(e){c.e=e}finally{await c.d()}}async function h({config:e,cwd:t,db:n,env:r,modules:i}){try{await g(n,i.schema)?(await s({config:e,cwd:t,env:r}),console.log(`Local database already set up`)):(console.log(`Local database is missing or unseeded; running setup`),await c(`default`,{config:e,cwd:t,env:r}))}finally{await _(n)}}async function g(e,t){try{return await p(e,t)}catch{return!1}}async function _(e){await e.$client?.close?.(),await e.$client?.end?.()}export{m as ensureLocalDb};
package/dist/index.d.ts CHANGED
@@ -1,19 +1,20 @@
1
1
  import { SeedDatabase, SeedQuery, applySeed } from "./apply-seed.js";
2
2
  import { checkDeployMigrations } from "./check-migrations.js";
3
- import { CreateDatabaseAdapterOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, QueryResult, createDatabaseAdapter, normalizeQueryResult } from "./client.js";
3
+ import { CreateDatabaseAdapterOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, PostgresDrizzleExecutor, QueryResult, SqliteDrizzleExecutor, createDatabaseAdapter, normalizeQueryResult } from "./client.js";
4
4
  import { HELD_MIGRATIONS_FOLDER, MIGRATIONS_FOLDER, NOW, SEED_EMAILS, SEED_IDS, SeedProfile, generatedUserId, getSeedProfile } from "./config.js";
5
5
  import { runDrizzleKitCommand } from "./drizzle-kit.js";
6
6
  import { ensureLocalDb } from "./ensure.js";
7
7
  import { formatDbErrorMessage } from "./error.js";
8
- import { CreateProjectDatabaseOptions, createProjectDeployDatabase, createProjectPostgresDrizzleDatabase, createProjectSqliteDrizzleDatabase } from "./project.js";
9
- import { LOCAL_POSTGRES_ENV_FLAG, LocalPostgresDb, ProjectPostgresAlreadyRunningError, ProjectPostgresSidecar, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, createLocalPostgresDb, createLocalPostgresEnv, getLocalPostgresConnectionString, startProjectPostgres, startTemporaryProjectPostgres, stopProjectPostgres } from "./local-postgres.js";
10
- import { heldMigrationInsertQuery, heldMigrationSelectQuery, migrateHeldMigrations, validateHeldMigrationHeader } from "./migrate-held.js";
8
+ import { CreateProjectDatabaseOptions, ProjectPostgresDrizzleDatabase, ProjectSqliteDrizzleDatabase, createProjectPostgresDatabaseAdapter, createProjectPostgresDrizzleDatabase, createProjectSqliteDatabaseAdapter, createProjectSqliteDrizzleDatabase } from "./project.js";
9
+ import { LOCAL_POSTGRES_ENV_FLAG, LocalPostgresDb, ProjectPostgresAlreadyRunningError, ProjectPostgresSidecar, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, createLocalPostgresDatabaseAdapter, createLocalPostgresDb, createLocalPostgresEnv, getLocalPostgresConnectionString, startProjectPostgres, startTemporaryProjectPostgres, stopProjectPostgres } from "./local-postgres.js";
10
+ import { LOCAL_TURSO_ENV_FLAG, ProjectTursoSidecar, createLocalTursoEnv, startProjectTurso, startTemporaryProjectTurso } from "./local-turso.js";
11
+ import { HeldMigrationTarget, MigrateHeldMigrationsOptions, heldMigrationInsertQuery, heldMigrationSelectQuery, migrateHeldMigrations, validateHeldMigrationHeader } from "./migrate-held.js";
11
12
  import { migrateLocalDb } from "./migrate.js";
12
13
  import { MigrationFile, MigrationRisk, MigrationScanResult, collectDeployMigrationFiles, collectHeldMigrationFiles, formatMigrationList, formatMigrationScanFailures, scanDeployMigrationFiles, scanMigrationSql } from "./migrations.js";
13
14
  import { appliedMigrationsQuery, filterPendingMigrations, readAppliedMigrationNames } from "./pending-migrations.js";
14
15
  import { resetLocalDb } from "./reset.js";
15
16
  import { checkSchemaPush } from "./schema-check.js";
16
- import { SchemaPushModule, SchemaPushPlan, inferSchemaDialect, planLocalSchemaPush } from "./schema-push.js";
17
+ import { SchemaPushDatabase, SchemaPushModule, SchemaPushPlan, inferSchemaDialect, planLocalSchemaPush } from "./schema-push.js";
17
18
  import { runProjectSeed, seedLocalDb } from "./seed.js";
18
19
  import { setupLocalDb } from "./setup.js";
19
- export { CreateDatabaseAdapterOptions, CreateProjectDatabaseOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, HELD_MIGRATIONS_FOLDER, LOCAL_POSTGRES_ENV_FLAG, LocalPostgresDb, MIGRATIONS_FOLDER, MigrationFile, MigrationRisk, MigrationScanResult, NOW, ProjectPostgresAlreadyRunningError, ProjectPostgresSidecar, QueryResult, SEED_EMAILS, SEED_IDS, SchemaPushModule, SchemaPushPlan, SeedDatabase, SeedProfile, SeedQuery, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, appliedMigrationsQuery, applySeed, checkDeployMigrations, checkSchemaPush, collectDeployMigrationFiles, collectHeldMigrationFiles, createDatabaseAdapter, createLocalPostgresDb, createLocalPostgresEnv, createProjectDeployDatabase, createProjectPostgresDrizzleDatabase, createProjectSqliteDrizzleDatabase, ensureLocalDb, filterPendingMigrations, formatDbErrorMessage, formatMigrationList, formatMigrationScanFailures, generatedUserId, getLocalPostgresConnectionString, getSeedProfile, heldMigrationInsertQuery, heldMigrationSelectQuery, inferSchemaDialect, migrateHeldMigrations, migrateLocalDb, normalizeQueryResult, planLocalSchemaPush, readAppliedMigrationNames, resetLocalDb, runDrizzleKitCommand, runProjectSeed, scanDeployMigrationFiles, scanMigrationSql, seedLocalDb, setupLocalDb, startProjectPostgres, startTemporaryProjectPostgres, stopProjectPostgres, validateHeldMigrationHeader };
20
+ export { CreateDatabaseAdapterOptions, CreateProjectDatabaseOptions, DatabaseClient, DatabaseDialect, DrizzleExecutor, HELD_MIGRATIONS_FOLDER, HeldMigrationTarget, LOCAL_POSTGRES_ENV_FLAG, LOCAL_TURSO_ENV_FLAG, LocalPostgresDb, MIGRATIONS_FOLDER, MigrateHeldMigrationsOptions, MigrationFile, MigrationRisk, MigrationScanResult, NOW, PostgresDrizzleExecutor, ProjectPostgresAlreadyRunningError, ProjectPostgresDrizzleDatabase, ProjectPostgresSidecar, ProjectSqliteDrizzleDatabase, ProjectTursoSidecar, QueryResult, SEED_EMAILS, SEED_IDS, SchemaPushDatabase, SchemaPushModule, SchemaPushPlan, SeedDatabase, SeedProfile, SeedQuery, SqliteDrizzleExecutor, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, appliedMigrationsQuery, applySeed, checkDeployMigrations, checkSchemaPush, collectDeployMigrationFiles, collectHeldMigrationFiles, createDatabaseAdapter, createLocalPostgresDatabaseAdapter, createLocalPostgresDb, createLocalPostgresEnv, createLocalTursoEnv, createProjectPostgresDatabaseAdapter, createProjectPostgresDrizzleDatabase, createProjectSqliteDatabaseAdapter, createProjectSqliteDrizzleDatabase, ensureLocalDb, filterPendingMigrations, formatDbErrorMessage, formatMigrationList, formatMigrationScanFailures, generatedUserId, getLocalPostgresConnectionString, getSeedProfile, heldMigrationInsertQuery, heldMigrationSelectQuery, inferSchemaDialect, migrateHeldMigrations, migrateLocalDb, normalizeQueryResult, planLocalSchemaPush, readAppliedMigrationNames, resetLocalDb, runDrizzleKitCommand, runProjectSeed, scanDeployMigrationFiles, scanMigrationSql, seedLocalDb, setupLocalDb, startProjectPostgres, startProjectTurso, startTemporaryProjectPostgres, startTemporaryProjectTurso, stopProjectPostgres, validateHeldMigrationHeader };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{applySeed as e}from"./apply-seed.js";import{HELD_MIGRATIONS_FOLDER as t,MIGRATIONS_FOLDER as n,NOW as r,SEED_EMAILS as i,SEED_IDS as a,generatedUserId as o,getSeedProfile as s}from"./config.js";import{collectDeployMigrationFiles as c,collectHeldMigrationFiles as l,formatMigrationList as u,formatMigrationScanFailures as d,scanDeployMigrationFiles as f,scanMigrationSql as p}from"./migrations.js";import{checkDeployMigrations as m}from"./check-migrations.js";import{createDatabaseAdapter as h,normalizeQueryResult as g}from"./client.js";import{createProjectDeployDatabase as _,createProjectPostgresDrizzleDatabase as v,createProjectSqliteDrizzleDatabase as y}from"./project.js";import{LOCAL_POSTGRES_ENV_FLAG as b,ProjectPostgresAlreadyRunningError as x,createLocalPostgresDb as S,createLocalPostgresEnv as C,getLocalPostgresConnectionString as w,startProjectPostgres as T,startTemporaryProjectPostgres as E,stopProjectPostgres as D}from"./local-postgres.js";import{runDrizzleKitCommand as O}from"./drizzle-kit.js";import{inferSchemaDialect as k,planLocalSchemaPush as A}from"./schema-push.js";import{runProjectSeed as j,seedLocalDb as M}from"./seed.js";import{migrateLocalDb as N}from"./migrate.js";import{resetLocalDb as P}from"./reset.js";import{setupLocalDb as F}from"./setup.js";import{ensureLocalDb as I}from"./ensure.js";import{formatDbErrorMessage as L}from"./error.js";import{heldMigrationInsertQuery as R,heldMigrationSelectQuery as z,migrateHeldMigrations as B,validateHeldMigrationHeader as V}from"./migrate-held.js";import{appliedMigrationsQuery as H,filterPendingMigrations as U,readAppliedMigrationNames as W}from"./pending-migrations.js";import{checkSchemaPush as G}from"./schema-check.js";export{t as HELD_MIGRATIONS_FOLDER,b as LOCAL_POSTGRES_ENV_FLAG,n as MIGRATIONS_FOLDER,r as NOW,x as ProjectPostgresAlreadyRunningError,i as SEED_EMAILS,a as SEED_IDS,H as appliedMigrationsQuery,e as applySeed,m as checkDeployMigrations,G as checkSchemaPush,c as collectDeployMigrationFiles,l as collectHeldMigrationFiles,h as createDatabaseAdapter,S as createLocalPostgresDb,C as createLocalPostgresEnv,_ as createProjectDeployDatabase,v as createProjectPostgresDrizzleDatabase,y as createProjectSqliteDrizzleDatabase,I as ensureLocalDb,U as filterPendingMigrations,L as formatDbErrorMessage,u as formatMigrationList,d as formatMigrationScanFailures,o as generatedUserId,w as getLocalPostgresConnectionString,s as getSeedProfile,R as heldMigrationInsertQuery,z as heldMigrationSelectQuery,k as inferSchemaDialect,B as migrateHeldMigrations,N as migrateLocalDb,g as normalizeQueryResult,A as planLocalSchemaPush,W as readAppliedMigrationNames,P as resetLocalDb,O as runDrizzleKitCommand,j as runProjectSeed,f as scanDeployMigrationFiles,p as scanMigrationSql,M as seedLocalDb,F as setupLocalDb,T as startProjectPostgres,E as startTemporaryProjectPostgres,D as stopProjectPostgres,V as validateHeldMigrationHeader};
1
+ import{applySeed as e}from"./apply-seed.js";import{HELD_MIGRATIONS_FOLDER as t,MIGRATIONS_FOLDER as n,NOW as r,SEED_EMAILS as i,SEED_IDS as a,generatedUserId as o,getSeedProfile as s}from"./config.js";import{collectDeployMigrationFiles as c,collectHeldMigrationFiles as l,formatMigrationList as u,formatMigrationScanFailures as d,scanDeployMigrationFiles as f,scanMigrationSql as p}from"./migrations.js";import{checkDeployMigrations as m}from"./check-migrations.js";import{createDatabaseAdapter as h,normalizeQueryResult as g}from"./client.js";import{createProjectPostgresDatabaseAdapter as _,createProjectPostgresDrizzleDatabase as v,createProjectSqliteDatabaseAdapter as y,createProjectSqliteDrizzleDatabase as b}from"./project.js";import{LOCAL_POSTGRES_ENV_FLAG as x,ProjectPostgresAlreadyRunningError as S,createLocalPostgresDatabaseAdapter as C,createLocalPostgresDb as w,createLocalPostgresEnv as T,getLocalPostgresConnectionString as E,startProjectPostgres as D,startTemporaryProjectPostgres as O,stopProjectPostgres as k}from"./local-postgres.js";import{LOCAL_TURSO_ENV_FLAG as A,createLocalTursoEnv as j,startProjectTurso as M,startTemporaryProjectTurso as N}from"./local-turso.js";import{runDrizzleKitCommand as P}from"./drizzle-kit.js";import{migrateLocalDb as F}from"./migrate.js";import{inferSchemaDialect as I,planLocalSchemaPush as L}from"./schema-push.js";import{resetLocalDb as R}from"./reset.js";import{runProjectSeed as z,seedLocalDb as B}from"./seed.js";import{setupLocalDb as V}from"./setup.js";import{ensureLocalDb as H}from"./ensure.js";import{formatDbErrorMessage as U}from"./error.js";import{heldMigrationInsertQuery as W,heldMigrationSelectQuery as G,migrateHeldMigrations as K,validateHeldMigrationHeader as q}from"./migrate-held.js";import{appliedMigrationsQuery as J,filterPendingMigrations as Y,readAppliedMigrationNames as X}from"./pending-migrations.js";import{checkSchemaPush as Z}from"./schema-check.js";export{t as HELD_MIGRATIONS_FOLDER,x as LOCAL_POSTGRES_ENV_FLAG,A as LOCAL_TURSO_ENV_FLAG,n as MIGRATIONS_FOLDER,r as NOW,S as ProjectPostgresAlreadyRunningError,i as SEED_EMAILS,a as SEED_IDS,J as appliedMigrationsQuery,e as applySeed,m as checkDeployMigrations,Z as checkSchemaPush,c as collectDeployMigrationFiles,l as collectHeldMigrationFiles,h as createDatabaseAdapter,C as createLocalPostgresDatabaseAdapter,w as createLocalPostgresDb,T as createLocalPostgresEnv,j as createLocalTursoEnv,_ as createProjectPostgresDatabaseAdapter,v as createProjectPostgresDrizzleDatabase,y as createProjectSqliteDatabaseAdapter,b as createProjectSqliteDrizzleDatabase,H as ensureLocalDb,Y as filterPendingMigrations,U as formatDbErrorMessage,u as formatMigrationList,d as formatMigrationScanFailures,o as generatedUserId,E as getLocalPostgresConnectionString,s as getSeedProfile,W as heldMigrationInsertQuery,G as heldMigrationSelectQuery,I as inferSchemaDialect,K as migrateHeldMigrations,F as migrateLocalDb,g as normalizeQueryResult,L as planLocalSchemaPush,X as readAppliedMigrationNames,R as resetLocalDb,P as runDrizzleKitCommand,z as runProjectSeed,f as scanDeployMigrationFiles,p as scanMigrationSql,B as seedLocalDb,V as setupLocalDb,D as startProjectPostgres,M as startProjectTurso,O as startTemporaryProjectPostgres,N as startTemporaryProjectTurso,k as stopProjectPostgres,q as validateHeldMigrationHeader};
@@ -1,4 +1,4 @@
1
- import { DrizzleExecutor } from "./client.js";
1
+ import { DatabaseClient } from "./client.js";
2
2
  import { createProjectPostgresDrizzleDatabase } from "./project.js";
3
3
  import { CoreframeConfig } from "@coreframe/config";
4
4
  import { LocalPostgresEnv, PostgresOutputTarget } from "local-postgres";
@@ -9,16 +9,6 @@ type LocalPostgresDb = Awaited<ReturnType<typeof createProjectPostgresDrizzleDat
9
9
  $client: {
10
10
  end(): Promise<void>;
11
11
  };
12
- transaction<Result>(run: (database: DrizzleExecutor) => Promise<Result>): Promise<Result>;
13
- select(selection: Record<string, unknown>): {
14
- from(table: unknown): {
15
- where(condition: unknown): {
16
- limit(count: number): Promise<Array<{
17
- id: string;
18
- }>>;
19
- };
20
- };
21
- };
22
12
  };
23
13
  type LocalPostgresOptions = {
24
14
  cwd?: string;
@@ -64,6 +54,11 @@ declare function createLocalPostgresDb({
64
54
  cwd,
65
55
  env
66
56
  }?: LocalPostgresOptions): Promise<LocalPostgresDb>;
57
+ /** Creates a held-migration-compatible adapter for the managed local PostgreSQL database. */
58
+ declare function createLocalPostgresDatabaseAdapter({
59
+ cwd,
60
+ env
61
+ }?: LocalPostgresOptions): Promise<DatabaseClient>;
67
62
  declare function getLocalPostgresConnectionString(env?: NodeJS.ProcessEnv): string;
68
63
  //#endregion
69
- export { LOCAL_POSTGRES_ENV_FLAG, LocalPostgresDb, ProjectPostgresAlreadyRunningError, ProjectPostgresSidecar, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, createLocalPostgresDb, createLocalPostgresEnv, getLocalPostgresConnectionString, startProjectPostgres, startTemporaryProjectPostgres, stopProjectPostgres };
64
+ export { LOCAL_POSTGRES_ENV_FLAG, LocalPostgresDb, ProjectPostgresAlreadyRunningError, ProjectPostgresSidecar, StartProjectPostgresOptions, StartTemporaryProjectPostgresOptions, createLocalPostgresDatabaseAdapter, createLocalPostgresDb, createLocalPostgresEnv, getLocalPostgresConnectionString, startProjectPostgres, startTemporaryProjectPostgres, stopProjectPostgres };
@@ -1 +1 @@
1
- import{fs as e,os as t}from"./environment.js";import{createProjectPostgresDrizzleDatabase as n}from"./project.js";import r from"node:path";import{readProjectConfig as i}from"@coreframe/config";import{connectExistingDevSupervisor as a}from"@coreframe/dev-supervisor";import{startPostgres as o}from"local-postgres";import{PostgresDataDirInUseError as s,stopPostgresDataDir as c}from"local-postgres/core";const l=`COREFRAME_LOCAL_POSTGRES`,u=`coreframe`,d=2e3,f=4e3,p=new Map,m={name:`coreframe`,password:`coreframe`};var h=class extends Error{dataDir;pid;constructor(e,t,n){super(`PostgreSQL is already running for this project (PID ${t}). Stop the other top-level \`coreframe dev\` process before starting another.`,n),this.name=`ProjectPostgresAlreadyRunningError`,this.dataDir=e,this.pid=t}};async function g({config:t,cwd:n=process.cwd(),env:s=process.env,failIfRunning:c=!1,postgresOutput:l,useSupervisorLease:f=!1}={}){if(s.COREFRAME_LOCAL_POSTGRES===`1`)return T(s);let p=t??await i({cwd:n});if((p.database?.dialect??`postgres`)!==`postgres`)return T(s);if(f){if(s.COREFRAME_DEV_SUPERVISOR!==`0`){let e=await a({cwd:n,env:s});if(e)try{let t=await e.acquirePostgres({config:p,env:s});return E(e,t.leaseId,t.env)}catch(t){throw e.close(),t}}return v({config:p,cwd:n,env:s})}let g=r.resolve(n,`.coreframe/postgres`),_=await D(g);if(_){if(c)throw new h(g,_.pid);return T(O(s,g,_))}let y=r.join(g,`postgres.log`);await e.rm(y,{force:!0});let b;try{b=await o({dataDir:g,database:u,postgresOutput:l??{filePath:y},postgres:{strategy:`prefer-local`},stopTimeoutMs:d,superuser:m})}catch(e){throw await k(e,l?void 0:y)}return x(s,b)}async function _({dataDir:e,pid:t}){let n=`${e}\0${t}`,r=p.get(n);if(r){await r;return}let i=C(e,t);p.set(n,i);try{await i}finally{p.get(n)===i&&p.delete(n)}}async function v({config:n,cwd:a=process.cwd(),env:s=process.env}={}){let c=(n??await i({cwd:a})).database?.dialect??`postgres`;if(c!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL, but this project uses ${c}.`);let l=await e.mkdtemp(r.join(t.tmpdir(),`coreframe-schema-check-`));try{let t=x(s,await o({dataDir:l,database:u,postgresOutput:`ignore`,postgres:{strategy:`prefer-local`},stopTimeoutMs:d,superuser:m}));return{env:t.env,async[Symbol.asyncDispose](){await t[Symbol.asyncDispose](),await e.rm(l,{force:!0,recursive:!0})}}}catch(e){throw await w(l,e),e}}function y(e,t){return{...e,...t,[l]:`1`}}async function b({cwd:e=process.cwd(),env:t=process.env}={}){let r=j(t);return n({cwd:e,env:{...t,DATABASE_URL:r}})}function x(e,t){let n;return{env:y(e,t.env),async[Symbol.asyncDispose](){n??=S(t),await n}}}async function S(e){let t;try{await e[Symbol.asyncDispose]()}catch(e){t=e}if(e.pid===void 0){if(t)throw t;return}try{await c({dataDir:e.dataDir,expectedPid:e.pid,mode:`immediate`,timeoutMs:f})}catch(n){throw t?AggregateError([t,n],`Failed to stop PostgreSQL process ${e.pid}.`):n}}async function C(e,t){try{await c({dataDir:e,expectedPid:t,mode:`fast`,timeoutMs:f})}catch(n){try{await c({dataDir:e,expectedPid:t,mode:`immediate`,timeoutMs:f})}catch(e){throw AggregateError([n,e],`Failed to stop PostgreSQL process ${t}.`)}}}async function w(t,n){try{await c({dataDir:t,mode:`immediate`,timeoutMs:f})}catch(e){throw AggregateError([n,e],`Temporary PostgreSQL failed to start and could not be stopped for ${t}.`)}await e.rm(t,{force:!0,recursive:!0})}function T(e){return{env:e,async[Symbol.asyncDispose](){}}}function E(e,t,n){let r;return{env:n,async[Symbol.asyncDispose](){r??=(async()=>{try{await e.release(t)}finally{e.close()}})(),await r}}}async function D(n){let i;try{i=await e.readFile(r.join(n,`postmaster.pid`),`utf8`)}catch{return}let[a,,,o,,s]=i.split(/\r?\n/),c=Number(a);if(!Number.isSafeInteger(c)||c<=0)return;try{t.kill(c,0)}catch(e){if(!A(e)||e.code!==`EPERM`)return}let l=Number(o);if(!Number.isSafeInteger(l)||l<=0||l>65535||!s)throw Error(`Cannot read connection details for PostgreSQL process ${c} from ${n}.`);return{host:s,pid:c,port:l}}function O(e,t,{host:n,port:r}){let i=new URL(`postgresql://${n}:${r}/${u}`);return i.username=m.name,i.password=m.password,y(e,{DATABASE_URL:i.href,PGDATA:t,PGDATABASE:u,PGHOST:n,PGPASSWORD:m.password,PGPORT:String(r),PGUSER:m.name})}async function k(t,n){if(t instanceof s)return new h(t.dataDir,t.pid,{cause:t});let r=t instanceof Error?t.message:String(t),i;if(n)try{i=(await e.readFile(n,`utf8`)).trim()||void 0}catch{}let a=i?`\n\nPostgreSQL output:\n${i}`:``,o=n?`\n\nPostgreSQL log: ${n}`:``;return Error(`Local PostgreSQL failed to start: ${r}${a}${o}`,{cause:t})}function A(e){return e instanceof Error}function j(e=process.env){let t=e.DATABASE_URL||M(e);if(!t)throw Error(`DATABASE_URL or PGDATABASE, PGHOST, PGPORT, and PGUSER are required.`);return t}function M(e){let{PGDATABASE:t,PGHOST:n,PGPASSWORD:r,PGPORT:i,PGUSER:a}=e;if(!t||!n||!i||!a)return;let o=new URL(`postgresql://${n}:${i}/${t}`);return o.username=a,r&&(o.password=r),o.href}export{l as LOCAL_POSTGRES_ENV_FLAG,h as ProjectPostgresAlreadyRunningError,b as createLocalPostgresDb,y as createLocalPostgresEnv,j as getLocalPostgresConnectionString,g as startProjectPostgres,v as startTemporaryProjectPostgres,_ as stopProjectPostgres};
1
+ import{createDatabaseAdapter as e}from"./client.js";import{fs as t,os as n}from"./environment.js";import{createProjectPostgresDrizzleDatabase as r}from"./project.js";import i from"node:path";import{readProjectConfig as a}from"@coreframe/config";import{connectExistingDevSupervisor as o}from"@coreframe/dev-supervisor";import{startPostgres as s}from"local-postgres";import{PostgresDataDirInUseError as c,stopPostgresDataDir as l}from"local-postgres/core";const u=`COREFRAME_LOCAL_POSTGRES`,d=`coreframe`,f=2e3,p=4e3,m=new Map,h={name:`coreframe`,password:`coreframe`};var g=class extends Error{dataDir;pid;constructor(e,t,n){super(`PostgreSQL is already running for this project (PID ${t}). Stop the other top-level \`coreframe dev\` process before starting another.`,n),this.name=`ProjectPostgresAlreadyRunningError`,this.dataDir=e,this.pid=t}};async function _({config:e,cwd:n=process.cwd(),env:r=process.env,failIfRunning:c=!1,postgresOutput:l,useSupervisorLease:u=!1}={}){if(r.COREFRAME_LOCAL_POSTGRES===`1`)return D(r);let p=e??await a({cwd:n});if((p.database?.dialect??`postgres`)!==`postgres`)return D(r);if(u){if(r.COREFRAME_DEV_SUPERVISOR!==`0`){let e=await o({cwd:n,env:r});if(e)try{let t=await e.acquirePostgres({config:p,env:r});return O(e,t.leaseId,t.env)}catch(t){throw e.close(),t}}return y({config:p,cwd:n,env:r})}let m=i.resolve(n,`.coreframe/postgres`),_=await k(m);if(_){if(c)throw new g(m,_.pid);return D(A(r,m,_))}let v=i.join(m,`postgres.log`);await t.rm(v,{force:!0});let b;try{b=await s({dataDir:m,database:d,postgresOutput:l??{filePath:v},postgres:{strategy:`prefer-local`},stopTimeoutMs:f,superuser:h})}catch(e){throw await j(e,l?void 0:v)}return C(r,b)}async function v({dataDir:e,pid:t}){let n=`${e}\0${t}`,r=m.get(n);if(r){await r;return}let i=T(e,t);m.set(n,i);try{await i}finally{m.get(n)===i&&m.delete(n)}}async function y({config:e,cwd:r=process.cwd(),env:o=process.env}={}){let c=(e??await a({cwd:r})).database?.dialect??`postgres`;if(c!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL, but this project uses ${c}.`);let l=await t.mkdtemp(i.join(n.tmpdir(),`coreframe-schema-check-`));try{let e=C(o,await s({dataDir:l,database:d,postgresOutput:`ignore`,postgres:{strategy:`prefer-local`},stopTimeoutMs:f,superuser:h}));return{env:e.env,async[Symbol.asyncDispose](){await e[Symbol.asyncDispose](),await t.rm(l,{force:!0,recursive:!0})}}}catch(e){throw await E(l,e),e}}function b(e,t){return{...e,...t,[u]:`1`}}async function x({cwd:e=process.cwd(),env:t=process.env}={}){let n=N(t);return r({cwd:e,env:{...t,DATABASE_URL:n}})}async function S({cwd:t=process.cwd(),env:n=process.env}={}){let r=await x({cwd:t,env:n});return e({database:r,dialect:`postgres`,close:()=>r.$client.end()})}function C(e,t){let n;return{env:b(e,t.env),async[Symbol.asyncDispose](){n??=w(t),await n}}}async function w(e){let t;try{await e[Symbol.asyncDispose]()}catch(e){t=e}if(e.pid===void 0){if(t)throw t;return}try{await l({dataDir:e.dataDir,expectedPid:e.pid,mode:`immediate`,timeoutMs:p})}catch(n){throw t?AggregateError([t,n],`Failed to stop PostgreSQL process ${e.pid}.`):n}}async function T(e,t){try{await l({dataDir:e,expectedPid:t,mode:`fast`,timeoutMs:p})}catch(n){try{await l({dataDir:e,expectedPid:t,mode:`immediate`,timeoutMs:p})}catch(e){throw AggregateError([n,e],`Failed to stop PostgreSQL process ${t}.`)}}}async function E(e,n){try{await l({dataDir:e,mode:`immediate`,timeoutMs:p})}catch(t){throw AggregateError([n,t],`Temporary PostgreSQL failed to start and could not be stopped for ${e}.`)}await t.rm(e,{force:!0,recursive:!0})}function D(e){return{env:e,async[Symbol.asyncDispose](){}}}function O(e,t,n){let r;return{env:n,async[Symbol.asyncDispose](){r??=(async()=>{try{await e.release(t)}finally{e.close()}})(),await r}}}async function k(e){let r;try{r=await t.readFile(i.join(e,`postmaster.pid`),`utf8`)}catch{return}let[a,,,o,,s]=r.split(/\r?\n/),c=Number(a);if(!Number.isSafeInteger(c)||c<=0)return;try{n.kill(c,0)}catch(e){if(!M(e)||e.code!==`EPERM`)return}let l=Number(o);if(!Number.isSafeInteger(l)||l<=0||l>65535||!s)throw Error(`Cannot read connection details for PostgreSQL process ${c} from ${e}.`);return{host:s,pid:c,port:l}}function A(e,t,{host:n,port:r}){let i=new URL(`postgresql://${n}:${r}/${d}`);return i.username=h.name,i.password=h.password,b(e,{DATABASE_URL:i.href,PGDATA:t,PGDATABASE:d,PGHOST:n,PGPASSWORD:h.password,PGPORT:String(r),PGUSER:h.name})}async function j(e,n){if(e instanceof c)return new g(e.dataDir,e.pid,{cause:e});let r=e instanceof Error?e.message:String(e),i;if(n)try{i=(await t.readFile(n,`utf8`)).trim()||void 0}catch{}let a=i?`\n\nPostgreSQL output:\n${i}`:``,o=n?`\n\nPostgreSQL log: ${n}`:``;return Error(`Local PostgreSQL failed to start: ${r}${a}${o}`,{cause:e})}function M(e){return e instanceof Error}function N(e=process.env){let t=e.DATABASE_URL||P(e);if(!t)throw Error(`DATABASE_URL or PGDATABASE, PGHOST, PGPORT, and PGUSER are required.`);return t}function P(e){let{PGDATABASE:t,PGHOST:n,PGPASSWORD:r,PGPORT:i,PGUSER:a}=e;if(!t||!n||!i||!a)return;let o=new URL(`postgresql://${n}:${i}/${t}`);return o.username=a,r&&(o.password=r),o.href}export{u as LOCAL_POSTGRES_ENV_FLAG,g as ProjectPostgresAlreadyRunningError,S as createLocalPostgresDatabaseAdapter,x as createLocalPostgresDb,b as createLocalPostgresEnv,N as getLocalPostgresConnectionString,_ as startProjectPostgres,y as startTemporaryProjectPostgres,v as stopProjectPostgres};
@@ -0,0 +1,40 @@
1
+ import { CoreframeConfig } from "@coreframe/config";
2
+ import { Writable } from "node:stream";
3
+
4
+ //#region src/local-turso.d.ts
5
+ declare const LOCAL_TURSO_ENV_FLAG = "COREFRAME_LOCAL_TURSO";
6
+ type LocalTursoOptions = {
7
+ config?: CoreframeConfig;
8
+ cwd?: string;
9
+ databaseFile?: string;
10
+ env?: NodeJS.ProcessEnv;
11
+ tursoOutput?: Writable;
12
+ useSupervisorLease?: boolean;
13
+ };
14
+ type ProjectTursoSidecar = {
15
+ env: NodeJS.ProcessEnv;
16
+ [Symbol.asyncDispose](): Promise<void>;
17
+ };
18
+ /**
19
+ * Starts a project-scoped local libSQL server backed by `.coreframe/turso.db`.
20
+ *
21
+ * A running development supervisor owns and reuses the process through a lease. Commands outside
22
+ * the supervisor start a short-lived server while retaining the SQLite file for later commands.
23
+ */
24
+ declare function startProjectTurso({
25
+ config,
26
+ cwd,
27
+ databaseFile,
28
+ env,
29
+ tursoOutput,
30
+ useSupervisorLease
31
+ }?: LocalTursoOptions): Promise<ProjectTursoSidecar>;
32
+ /** Starts an isolated libSQL server and removes its database files when disposed. */
33
+ declare function startTemporaryProjectTurso({
34
+ config,
35
+ cwd,
36
+ env
37
+ }?: Omit<LocalTursoOptions, "databaseFile" | "tursoOutput" | "useSupervisorLease">): Promise<ProjectTursoSidecar>;
38
+ declare function createLocalTursoEnv(env: NodeJS.ProcessEnv, port: number): NodeJS.ProcessEnv;
39
+ //#endregion
40
+ export { LOCAL_TURSO_ENV_FLAG, ProjectTursoSidecar, createLocalTursoEnv, startProjectTurso, startTemporaryProjectTurso };
@@ -0,0 +1 @@
1
+ import{mkdir as e,mkdtemp as t,rm as n}from"node:fs/promises";import r from"node:path";import i from"node:process";import{readProjectConfig as a}from"@coreframe/config";import{connectExistingDevSupervisor as o}from"@coreframe/dev-supervisor";import{tmpdir as s}from"node:os";import{spawn as c}from"node:child_process";import{createConnection as l,createServer as u}from"node:net";const d=`COREFRAME_LOCAL_TURSO`,f=i.platform===`win32`?`turso.cmd`:`turso`;async function p({config:e,cwd:t=i.cwd(),databaseFile:n=r.resolve(t,`.coreframe/turso.db`),env:s=i.env,tursoOutput:c,useSupervisorLease:l=!1}={}){if(s.COREFRAME_LOCAL_TURSO===`1`)return _(s);let u=e??await a({cwd:t});if((u.database?.dialect??`postgres`)!==`sqlite`)return _(s);if(l&&s.COREFRAME_DEV_SUPERVISOR!==`0`){let e=await o({cwd:t,env:s});if(e)try{let t=await e.acquireSqlite({config:u,env:s});return v(e,t.leaseId,t.env)}catch(t){throw e.close(),t}}return g({cwd:t,databaseFile:n,env:s,tursoOutput:c})}async function m({config:e,cwd:o=i.cwd(),env:c=i.env}={}){let l=(e??await a({cwd:o})).database?.dialect??`postgres`;if(l!==`sqlite`)throw Error(`Temporary schema push checks require SQLite/libSQL, but this project uses ${l}.`);let u=await t(r.join(s(),`coreframe-schema-check-`));try{let e=await g({cwd:o,databaseFile:r.join(u,`turso.db`),env:c});return{env:e.env,async[Symbol.asyncDispose](){await e[Symbol.asyncDispose](),await n(u,{force:!0,recursive:!0})}}}catch(e){throw await n(u,{force:!0,recursive:!0}),e}}function h(e,t){let n=`http://127.0.0.1:${t}`;return{...e,DATABASE_URL:n,TURSO_AUTH_TOKEN:void 0,TURSO_DATABASE_URL:n,[d]:`1`}}async function g({cwd:t,databaseFile:n,env:i,tursoOutput:a}){await e(r.dirname(n),{recursive:!0});let o=await C(),s=h(i,o),l=c(f,[`dev`,`--port`,String(o),`--db-file`,n],{cwd:t,env:w(s),stdio:[`ignore`,`pipe`,`pipe`]});b(l,a);try{await x(l,o)}catch(e){throw await S(l),e}return y(s,l)}function _(e){return{env:e,async[Symbol.asyncDispose](){}}}function v(e,t,n){let r;return{env:n,async[Symbol.asyncDispose](){r??=(async()=>{try{await e.release(t)}finally{e.close()}})(),await r}}}function y(e,t){let n;return{env:e,async[Symbol.asyncDispose](){n??=S(t),await n}}}function b(e,t){t&&(e.stdout.on(`data`,e=>t.write(e)),e.stderr.on(`data`,e=>t.write(e)))}async function x(e,t){await new Promise((n,r)=>{let i=!1,a,o=setTimeout(()=>s(Error(`Turso did not start listening on port ${t} within 10 seconds.`)),1e4),s=t=>{i||(i=!0,clearTimeout(o),a&&clearTimeout(a),e.off(`error`,c),e.off(`exit`,u),t?r(t):n())},c=e=>s(e),u=(e,t)=>s(Error(`Turso exited before it started listening${e===null?``:` (code ${e})`}${t?` (${t})`:``}.`)),d=()=>{if(i)return;let e=l({host:`127.0.0.1`,port:t});e.once(`connect`,()=>{e.destroy(),s()}),e.once(`error`,()=>{e.destroy(),i||(a=setTimeout(d,50),a.unref())})};e.once(`error`,c),e.once(`exit`,u),d()})}async function S(e){e.exitCode!==null||e.signalCode!==null||await new Promise(t=>{let n=!1,r,i=()=>{n||(n=!0,r&&clearTimeout(r),e.off(`close`,i),e.off(`error`,i),e.off(`exit`,i),t())};r=setTimeout(()=>{e.kill(`SIGKILL`),i()},5e3),r.unref(),e.once(`close`,i),e.once(`error`,i),e.once(`exit`,i),!e.kill(`SIGTERM`)&&(e.exitCode!==null||e.signalCode!==null)&&i()})}async function C(){let e=u();try{await new Promise((t,n)=>{e.once(`error`,n),e.listen(0,`127.0.0.1`,t)});let t=e.address();if(!t||typeof t==`string`)throw Error(`Could not allocate an available TCP port for Turso.`);return t.port}finally{e.listening&&await new Promise((t,n)=>{e.close(e=>e?n(e):t())})}}function w(e){return Object.fromEntries(Object.entries(e).filter(e=>e[1]!==void 0))}export{d as LOCAL_TURSO_ENV_FLAG,h as createLocalTursoEnv,p as startProjectTurso,m as startTemporaryProjectTurso};
@@ -1,16 +1,22 @@
1
1
  import { DatabaseDialect } from "./client.js";
2
2
 
3
3
  //#region src/migrate-held.d.ts
4
- type MigrateHeldOptions = {
5
- argv?: string[];
4
+ /** Selects the database where held migrations are applied. */
5
+ type HeldMigrationTarget = "deployment" | "local";
6
+ /** Options for applying held migrations to a deployment or managed local PostgreSQL database. */
7
+ type MigrateHeldMigrationsOptions = {
8
+ cwd?: string;
6
9
  env?: NodeJS.ProcessEnv;
10
+ target?: HeldMigrationTarget;
7
11
  };
12
+ /** Applies held migrations to the selected database target. */
8
13
  declare function migrateHeldMigrations({
9
- argv,
10
- env
11
- }?: MigrateHeldOptions): Promise<void>;
14
+ cwd,
15
+ env,
16
+ target
17
+ }?: MigrateHeldMigrationsOptions): Promise<void>;
12
18
  declare function validateHeldMigrationHeader(sql: string, relativePath: string): void;
13
19
  declare function heldMigrationSelectQuery(dialect: DatabaseDialect, id: string): string;
14
20
  declare function heldMigrationInsertQuery(dialect: DatabaseDialect, id: string, sha256: string): string;
15
21
  //#endregion
16
- export { heldMigrationInsertQuery, heldMigrationSelectQuery, migrateHeldMigrations, validateHeldMigrationHeader };
22
+ export { HeldMigrationTarget, MigrateHeldMigrationsOptions, heldMigrationInsertQuery, heldMigrationSelectQuery, migrateHeldMigrations, validateHeldMigrationHeader };
@@ -1,4 +1,4 @@
1
- import{collectHeldMigrationFiles as e,formatMigrationList as t}from"./migrations.js";import{createProjectDeployDatabase as n}from"./project.js";import{readFile as r}from"node:fs/promises";import{createHash as i}from"node:crypto";const a=`--confirm=run-held-migrations`,o=[`-- Held migration:`,`-- Safe after:`,`-- Verification:`];async function s({argv:i=process.argv.slice(2),env:o=process.env}={}){let s=await e();if(console.log(`Held migration files:`),console.log(t(s)),!i.includes(a))throw Error(`Held migrations require explicit confirmation. Re-run with ${a}.`);if(s.length===0){console.log(`No held migrations to run.`);return}let d=await n({env:o});try{await u(d);for(let e of s){let t=await r(e.path,`utf8`);c(t,e.relativePath);let n=l(t),i=await d.execute(f(d.dialect,e.id));if(i.rows.length===1){if(i.rows[0]?.sha256!==n)throw Error(`Held migration ${e.relativePath} changed after it was applied.`);console.log(`Skipping already-applied held migration ${e.relativePath}`);continue}console.log(`Applying held migration ${e.relativePath}`),await h(d,async r=>{await r.execute(t),await r.execute(p(d.dialect,e.id,n))})}}finally{await d.close?.()}}function c(e,t){let n=o.filter(t=>!e.includes(t));if(n.length>0)throw Error(`${t} is missing held migration header fields: ${n.join(`, `)}`)}function l(e){return i(`sha256`).update(e).digest(`hex`)}async function u(e){for(let t of d(e.dialect))await e.execute(t)}function d(e){switch(e){case`postgres`:return[`create schema if not exists drizzle`,`create table if not exists drizzle.__held_migrations (
1
+ import{collectHeldMigrationFiles as e,formatMigrationList as t}from"./migrations.js";import{createProjectPostgresDatabaseAdapter as n,createProjectSqliteDatabaseAdapter as r}from"./project.js";import{createLocalPostgresDatabaseAdapter as i,startProjectPostgres as a}from"./local-postgres.js";import o from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{readFile as s}from"node:fs/promises";import{readProjectConfig as c}from"@coreframe/config";import{createHash as l}from"node:crypto";const u=[`-- Held migration:`,`-- Safe after:`,`-- Verification:`];async function d({cwd:s=process.cwd(),env:l=process.env,target:u=`deployment`}={}){let d=await e(s);if(console.log(`Held migration files:`),console.log(t(d)),d.length===0){console.log(`No held migrations to run.`);return}if(u===`local`)try{var p=o();let e=p.a(await a({cwd:s,env:l,useSupervisorLease:!0}));if(e.env.COREFRAME_LOCAL_POSTGRES!==`1`)throw Error(`Held migrations with --local require a Coreframe-managed PostgreSQL database.`);await f(()=>i({cwd:s,env:e.env}),d);return}catch(e){p.e=e}finally{await p.d()}let m=(await c({cwd:s})).database?.dialect??`postgres`;switch(m){case`postgres`:await f(()=>n({cwd:s,env:l}),d);return;case`sqlite`:await f(()=>r({cwd:s,env:l}),d);return;default:throw Error(`Unsupported database dialect "${m}".`)}}async function f(e,t){let n=await e();try{await p(n,t)}finally{await n.close?.()}}async function p(e,t){await g(e);for(let n of t){let t=await s(n.path,`utf8`);m(t,n.relativePath);let r=h(t),i=await e.execute(v(e.dialect,n.id));if(i.rows.length===1){if(i.rows[0]?.sha256!==r)throw Error(`Held migration ${n.relativePath} changed after it was applied.`);console.log(`Skipping already-applied held migration ${n.relativePath}`);continue}console.log(`Applying held migration ${n.relativePath}`),await x(e,async i=>{await i.execute(t),await i.execute(y(e.dialect,n.id,r))})}}function m(e,t){let n=u.filter(t=>!e.includes(t));if(n.length>0)throw Error(`${t} is missing held migration header fields: ${n.join(`, `)}`)}function h(e){return l(`sha256`).update(e).digest(`hex`)}async function g(e){for(let t of _(e.dialect))await e.execute(t)}function _(e){switch(e){case`postgres`:return[`create schema if not exists drizzle`,`create table if not exists drizzle.__held_migrations (
2
2
  id text primary key,
3
3
  sha256 text not null,
4
4
  applied_at timestamptz not null default now()
@@ -6,4 +6,4 @@ import{collectHeldMigrationFiles as e,formatMigrationList as t}from"./migrations
6
6
  id text primary key,
7
7
  sha256 text not null,
8
8
  applied_at text not null default current_timestamp
9
- )`]}}function f(e,t){return`select sha256 from ${m(e)} where id = ${g(t)}`}function p(e,t,n){return`insert into ${m(e)} (id, sha256) values (${g(t)}, ${g(n)})`}function m(e){switch(e){case`postgres`:return`drizzle.__held_migrations`;case`sqlite`:return`__held_migrations`}}async function h(e,t){if(e.transaction){await e.transaction(t);return}await e.execute(`begin`);try{await t(e),await e.execute(`commit`)}catch(t){throw await e.execute(`rollback`),t}}function g(e){return`'${e.replaceAll(`'`,`''`)}'`}export{p as heldMigrationInsertQuery,f as heldMigrationSelectQuery,s as migrateHeldMigrations,c as validateHeldMigrationHeader};
9
+ )`]}}function v(e,t){return`select sha256 from ${b(e)} where id = ${S(t)}`}function y(e,t,n){return`insert into ${b(e)} (id, sha256) values (${S(t)}, ${S(n)})`}function b(e){switch(e){case`postgres`:return`drizzle.__held_migrations`;case`sqlite`:return`__held_migrations`}}async function x(e,t){if(e.transaction){await e.transaction(t);return}await e.execute(`begin`);try{await t(e),await e.execute(`commit`)}catch(t){throw await e.execute(`rollback`),t}}function S(e){return`'${e.replaceAll(`'`,`''`)}'`}export{y as heldMigrationInsertQuery,v as heldMigrationSelectQuery,d as migrateHeldMigrations,m as validateHeldMigrationHeader};
package/dist/migrate.js CHANGED
@@ -1 +1 @@
1
- import{MIGRATIONS_FOLDER as e}from"./config.js";import{createProjectSqliteDrizzleDatabase as t}from"./project.js";import{createLocalPostgresDb as n,startProjectPostgres as r}from"./local-postgres.js";import i from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{access as a}from"node:fs/promises";import{resolve as o}from"node:path";import{readProjectConfig as s}from"@coreframe/config";import{migrate as c}from"drizzle-orm/libsql/migrator";import{migrate as l}from"drizzle-orm/node-postgres/migrator";async function u({config:u,cwd:d=process.cwd(),env:f=process.env}={}){try{var p=i();let m=u??await s({cwd:d}),h=o(d,e);if(await a(h),m.database?.dialect===`sqlite`){let e=await t({cwd:d,env:f});try{await c(e,{migrationsFolder:h}),console.log(`Applied local migrations from ${h}`)}finally{await e.$client?.close?.()}return}let g=await n({cwd:d,env:p.a(await r({env:f,useSupervisorLease:!0})).env});try{await l(g,{migrationsFolder:h}),console.log(`Applied local migrations from ${h}`)}finally{await g.$client.end()}}catch(e){p.e=e}finally{await p.d()}}export{u as migrateLocalDb};
1
+ import{MIGRATIONS_FOLDER as e}from"./config.js";import{createProjectSqliteDrizzleDatabase as t}from"./project.js";import{createLocalPostgresDb as n,startProjectPostgres as r}from"./local-postgres.js";import{startProjectTurso as i}from"./local-turso.js";import a from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{access as o}from"node:fs/promises";import{resolve as s}from"node:path";import{readProjectConfig as c}from"@coreframe/config";import{migrate as l}from"drizzle-orm/libsql/migrator";import{migrate as u}from"drizzle-orm/node-postgres/migrator";async function d({config:d,cwd:f=process.cwd(),env:p=process.env}={}){try{var m=a();let g=d??await c({cwd:f}),_=s(f,e);if(await o(_),g.database?.dialect===`sqlite`)try{var h=a();let e=await t({cwd:f,env:h.a(await i({config:g,cwd:f,env:p,useSupervisorLease:!0})).env});try{await l(e,{migrationsFolder:_}),console.log(`Applied local migrations from ${_}`)}finally{await e.$client?.close?.()}return}catch(e){h.e=e}finally{await h.d()}let v=await n({cwd:f,env:m.a(await r({config:g,cwd:f,env:p,useSupervisorLease:!0})).env});try{await u(v,{migrationsFolder:_}),console.log(`Applied local migrations from ${_}`)}finally{await v.$client.end()}}catch(e){m.e=e}finally{await m.d()}}export{d as migrateLocalDb};
package/dist/project.d.ts CHANGED
@@ -1,30 +1,29 @@
1
- import { DatabaseClient, DrizzleExecutor } from "./client.js";
2
- import { DatabaseConfig } from "@coreframe/config";
1
+ import { DatabaseClient } from "./client.js";
3
2
 
4
3
  //#region src/project.d.ts
5
4
  type CreateProjectDatabaseOptions = {
6
- config?: DatabaseConfig;
7
5
  cwd?: string;
8
6
  env?: NodeJS.ProcessEnv;
9
7
  };
10
- type DrizzleDatabase = DrizzleExecutor & {
11
- $client?: {
12
- close?(): Promise<void> | void;
13
- end?(): Promise<void>;
14
- };
15
- };
16
- declare function createProjectDeployDatabase({
17
- config,
8
+ type LibSqlDrizzleModule = typeof import("drizzle-orm/libsql");
9
+ type NodePostgresDrizzleModule = typeof import("drizzle-orm/node-postgres");
10
+ type ProjectPostgresDrizzleDatabase = ReturnType<NodePostgresDrizzleModule["drizzle"]>;
11
+ type ProjectSqliteDrizzleDatabase = ReturnType<LibSqlDrizzleModule["drizzle"]>;
12
+ declare function createProjectPostgresDatabaseAdapter({
18
13
  cwd,
19
14
  env
20
15
  }?: CreateProjectDatabaseOptions): Promise<DatabaseClient>;
21
16
  declare function createProjectPostgresDrizzleDatabase({
22
17
  cwd,
23
18
  env
24
- }?: CreateProjectDatabaseOptions): Promise<DrizzleDatabase>;
19
+ }?: CreateProjectDatabaseOptions): Promise<ProjectPostgresDrizzleDatabase>;
25
20
  declare function createProjectSqliteDrizzleDatabase({
26
21
  cwd,
27
22
  env
28
- }?: CreateProjectDatabaseOptions): Promise<DrizzleDatabase>;
23
+ }?: CreateProjectDatabaseOptions): Promise<ProjectSqliteDrizzleDatabase>;
24
+ declare function createProjectSqliteDatabaseAdapter({
25
+ cwd,
26
+ env
27
+ }?: CreateProjectDatabaseOptions): Promise<DatabaseClient>;
29
28
  //#endregion
30
- export { CreateProjectDatabaseOptions, createProjectDeployDatabase, createProjectPostgresDrizzleDatabase, createProjectSqliteDrizzleDatabase };
29
+ export { CreateProjectDatabaseOptions, ProjectPostgresDrizzleDatabase, ProjectSqliteDrizzleDatabase, createProjectPostgresDatabaseAdapter, createProjectPostgresDrizzleDatabase, createProjectSqliteDatabaseAdapter, createProjectSqliteDrizzleDatabase };
package/dist/project.js CHANGED
@@ -1 +1 @@
1
- import{createDatabaseAdapter as e}from"./client.js";import{importProjectDependency as t,importProjectModule as n,readProjectConfig as r}from"@coreframe/config";const i=`src/db/relations.ts`;async function a({config:e,cwd:t=process.cwd(),env:n=process.env}={}){let i=(e??(await r({cwd:t})).database)?.dialect??`postgres`;if(i===`postgres`)return c({cwd:t,env:n});if(i===`sqlite`)return l({cwd:t,env:n});throw Error(`Unsupported database dialect "${i}".`)}async function o({cwd:e=process.cwd(),env:r=process.env}={}){let a=r.DATABASE_URL;if(!a)throw Error(`DATABASE_URL is required to create the PostgreSQL database.`);let[{drizzle:o},{relations:s}]=await Promise.all([t(`drizzle-orm/node-postgres`,e),n(i,e)]);return o({connection:{connectionString:a,max:1},relations:s})}async function s({cwd:e=process.cwd(),env:r=process.env}={}){let a=r.TURSO_DATABASE_URL??r.DATABASE_URL;if(!a)throw Error(`TURSO_DATABASE_URL or DATABASE_URL is required to create the SQLite database.`);let[{createClient:o},{drizzle:s},{relations:c}]=await Promise.all([t(`@libsql/client`,e),t(`drizzle-orm/libsql`,e),n(i,e)]),l=o({url:a,authToken:r.TURSO_AUTH_TOKEN}),u=s({client:l,relations:c});return u.$client||=l,u}async function c({cwd:t,env:n}){let r=await o({cwd:t,env:n});return e({database:r,dialect:`postgres`,close:()=>r.$client?.end?.()??Promise.resolve()})}async function l({cwd:t,env:n}){let r=await s({cwd:t,env:n});return e({database:r,dialect:`sqlite`,close:async()=>{await r.$client?.close?.()}})}export{a as createProjectDeployDatabase,o as createProjectPostgresDrizzleDatabase,s as createProjectSqliteDrizzleDatabase};
1
+ import{createDatabaseAdapter as e}from"./client.js";import{importProjectDependency as t,importProjectModule as n}from"@coreframe/config";const r=`src/db/relations.ts`;async function i({cwd:t=process.cwd(),env:n=process.env}={}){let r=await a({cwd:t,env:n});return e({database:r,dialect:`postgres`,close:()=>r.$client?.end?.()??Promise.resolve()})}async function a({cwd:e=process.cwd(),env:i=process.env}={}){let a=i.DATABASE_URL;if(!a)throw Error(`DATABASE_URL is required to create the PostgreSQL database.`);let[{drizzle:o},{relations:s}]=await Promise.all([t(`drizzle-orm/node-postgres`,e),n(r,e)]);return o({connection:{connectionString:a,max:1},relations:s})}async function o({cwd:e=process.cwd(),env:i=process.env}={}){let a=i.TURSO_DATABASE_URL??i.DATABASE_URL;if(!a)throw Error(`TURSO_DATABASE_URL or DATABASE_URL is required to create the SQLite database.`);let[{createClient:o},{drizzle:s},{relations:c}]=await Promise.all([t(`@libsql/client`,e),t(`drizzle-orm/libsql`,e),n(r,e)]),l=o({url:a,authToken:i.TURSO_AUTH_TOKEN}),u=s({client:l,relations:c});return u.$client||=l,u}async function s({cwd:t=process.cwd(),env:n=process.env}={}){let r=await o({cwd:t,env:n});return e({database:r,dialect:`sqlite`,close:async()=>{r.$client.close()}})}export{i as createProjectPostgresDatabaseAdapter,a as createProjectPostgresDrizzleDatabase,s as createProjectSqliteDatabaseAdapter,o as createProjectSqliteDrizzleDatabase};
package/dist/reset.d.ts CHANGED
@@ -1,8 +1,14 @@
1
+ import { CoreframeConfig } from "@coreframe/config";
2
+
1
3
  //#region src/reset.d.ts
2
4
  type ResetLocalDbOptions = {
5
+ config?: CoreframeConfig;
6
+ cwd?: string;
3
7
  env?: NodeJS.ProcessEnv;
4
8
  };
5
9
  declare function resetLocalDb({
10
+ config,
11
+ cwd,
6
12
  env
7
13
  }?: ResetLocalDbOptions): Promise<void>;
8
14
  //#endregion
package/dist/reset.js CHANGED
@@ -1 +1,27 @@
1
- import{createLocalPostgresDb as e,startProjectPostgres as t}from"./local-postgres.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{sql as r}from"drizzle-orm";async function i({env:i=process.env}={}){try{var a=n();let o=await e({env:a.a(await t({env:i,useSupervisorLease:!0})).env});try{await o.transaction(async e=>{await e.execute(r`drop schema if exists public cascade`),await e.execute(r`drop schema if exists drizzle cascade`),await e.execute(r`create schema public`)}),console.log(`Reset local PostgreSQL schema`)}finally{await o.$client.end()}}catch(e){a.e=e}finally{await a.d()}}export{i as resetLocalDb};
1
+ import{collectDeployMigrationFiles as e}from"./migrations.js";import{createProjectSqliteDrizzleDatabase as t}from"./project.js";import{createLocalPostgresDb as n,startProjectPostgres as r}from"./local-postgres.js";import{startProjectTurso as i}from"./local-turso.js";import a from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as o,planLocalSchemaPush as s}from"./schema-push.js";import{readFile as c}from"node:fs/promises";import{sql as l}from"drizzle-orm";import{importProjectModule as u,readProjectConfig as d}from"@coreframe/config";import{createHash as f}from"node:crypto";async function p({config:t,cwd:c=process.cwd(),env:f=process.env}={}){try{var p=a();let _=t??await d({cwd:c}),v=await u(`src/db/schema.ts`,c),y=o(v),b=_.database?.dialect??`postgres`;if(y!==b)throw Error(`Configured ${b} database does not match the ${y} schema in src/db/schema.ts.`);if(b===`sqlite`)try{var h=a();await m({cwd:c,env:h.a(await i({config:_,cwd:c,env:f,useSupervisorLease:!0})).env,schema:v});return}catch(e){h.e=e}finally{await h.d()}let x=await n({cwd:c,env:p.a(await r({config:_,cwd:c,env:f,useSupervisorLease:!0})).env});try{await x.transaction(async e=>{await e.execute(l`drop schema if exists public cascade`),await e.execute(l`drop schema if exists drizzle cascade`),await e.execute(l`create schema public`)}),await(await s(`postgres`,v,x)).apply(),await g(x,await e(c)),console.log(`Reset local PostgreSQL schema from the current Drizzle schema`)}finally{await x.$client.end()}}catch(e){p.e=e}finally{await p.d()}}async function m({cwd:n,env:r,schema:i}){let a=await t({cwd:n,env:r}),o=!1;try{let t=await a.all(l`
2
+ select name, type
3
+ from sqlite_schema
4
+ where type in ('table', 'index', 'trigger', 'view') and name not like 'sqlite_%'
5
+ `);await a.run(l`pragma foreign_keys = off`),o=!0,await a.transaction(async e=>{for(let n of[`trigger`,`view`,`index`,`table`])for(let r of t.filter(e=>e.type===n))await e.run(l`drop ${l.raw(n)} if exists ${l.identifier(r.name)}`)}),await(await s(`sqlite`,i,a)).apply(),await _(a,await e(n)),console.log(`Reset local SQLite/libSQL schema from the current Drizzle schema`)}finally{o&&await a.run(l`pragma foreign_keys = on`).catch(()=>void 0),await a.$client?.close?.()}}async function h(e){return Promise.all(e.map(async e=>({migration:e,hash:f(`sha256`).update(await c(e.path)).digest(`hex`),createdAt:v(e.id)})))}async function g(e,t){let n=await h(t);await e.transaction(async e=>{await e.execute(l`create schema if not exists drizzle`),await e.execute(l`
6
+ create table if not exists drizzle.__drizzle_migrations (
7
+ id serial primary key,
8
+ hash text not null,
9
+ created_at bigint,
10
+ name text,
11
+ applied_at timestamp with time zone default now()
12
+ )
13
+ `);for(let{migration:t,hash:r,createdAt:i}of n)await e.execute(l`
14
+ insert into drizzle.__drizzle_migrations ("hash", "created_at", "name")
15
+ values (${r}, ${i}, ${t.id})
16
+ `)})}async function _(e,t){let n=await h(t),r=new Date().toISOString();await e.transaction(async e=>{await e.run(l`
17
+ create table if not exists __drizzle_migrations (
18
+ id integer primary key,
19
+ hash text not null,
20
+ created_at numeric,
21
+ name text,
22
+ applied_at text
23
+ )
24
+ `);for(let{migration:t,hash:i,createdAt:a}of n)await e.run(l`
25
+ insert into __drizzle_migrations ("hash", "created_at", "name", "applied_at")
26
+ values (${i}, ${a}, ${t.id}, ${r})
27
+ `)})}function v(e){let t=e.slice(0,14);return/^\d{14}$/u.test(t)?Date.UTC(Number(t.slice(0,4)),Number(t.slice(4,6))-1,Number(t.slice(6,8)),Number(t.slice(8,10)),Number(t.slice(10,12)),Number(t.slice(12,14))):null}export{p as resetLocalDb};
@@ -1,9 +1,15 @@
1
+ import { CoreframeConfig } from "@coreframe/config";
2
+
1
3
  //#region src/schema-check.d.ts
2
4
  type CheckSchemaPushOptions = {
5
+ config?: CoreframeConfig;
6
+ cwd?: string;
3
7
  env?: NodeJS.ProcessEnv;
4
8
  seed?: boolean;
5
9
  };
6
10
  declare function checkSchemaPush({
11
+ config,
12
+ cwd,
7
13
  env,
8
14
  seed
9
15
  }?: CheckSchemaPushOptions): Promise<void>;
@@ -1 +1 @@
1
- import{createLocalPostgresDb as e,startTemporaryProjectPostgres as t}from"./local-postgres.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as r,planLocalSchemaPush as i}from"./schema-push.js";import{runProjectSeed as a}from"./seed.js";import{importProjectModule as o}from"@coreframe/config";async function s({env:s=process.env,seed:l=!1}={}){try{var u=n();console.log(`Checking Drizzle schema against a throwaway PostgreSQL database`);let d=u.a(await t({env:s})),f=await o(`src/db/schema.ts`),p=await e({env:d.env});try{let e=r(f);if(e!==`postgres`)throw Error(`Temporary schema push checks require PostgreSQL schema, but found ${e}.`);let t=await i(e,f,p);t.sqlStatements.length===0?console.log(`Drizzle schema check passed with no changes`):(console.log(`Applying ${t.sqlStatements.length} statement(s) to throwaway database`),await t.apply(),console.log(`Drizzle schema check passed`)),l&&(console.log(`Seeding throwaway database`),await a(`default`,{env:d.env}),console.log(`Throwaway database seed check passed`))}finally{await c(p)}}catch(e){u.e=e}finally{await u.d()}}function c(e){return e.$client.end()}export{s as checkSchemaPush};
1
+ import{createProjectSqliteDrizzleDatabase as e}from"./project.js";import{createLocalPostgresDb as t,startTemporaryProjectPostgres as n}from"./local-postgres.js";import{startTemporaryProjectTurso as r}from"./local-turso.js";import i from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{inferSchemaDialect as a,planLocalSchemaPush as o}from"./schema-push.js";import{runProjectSeed as s}from"./seed.js";import{importProjectModule as c,readProjectConfig as l}from"@coreframe/config";async function u({config:a,cwd:o=process.cwd(),env:s=process.env,seed:u=!1}={}){try{var f=i();let m=a??await l({cwd:o}),h=await c(`src/db/schema.ts`,o);if(m.database?.dialect===`sqlite`)try{var p=i();console.log(`Checking Drizzle schema against a throwaway SQLite/libSQL database`);let t=p.a(await r({config:m,cwd:o,env:s}));await d({db:await e({cwd:o,env:t.env}),dialect:`sqlite`,env:t.env,schema:h,seed:u,cwd:o});return}catch(e){p.e=e}finally{await p.d()}console.log(`Checking Drizzle schema against a throwaway PostgreSQL database`);let g=f.a(await n({config:m,cwd:o,env:s}));await d({db:await t({cwd:o,env:g.env}),dialect:`postgres`,env:g.env,schema:h,seed:u,cwd:o})}catch(e){f.e=e}finally{await f.d()}}async function d({cwd:e,db:t,dialect:n,env:r,schema:i,seed:c}){try{let l=a(i);if(l!==n)throw Error(`Temporary ${n===`postgres`?`PostgreSQL`:`SQLite/libSQL`} schema push checks require ${n} schema, but found ${l}.`);let u=await o(n,i,t);u.sqlStatements.length===0?console.log(`Drizzle schema check passed with no changes`):(console.log(`Applying ${u.sqlStatements.length} statement(s) to throwaway database`),await u.apply(),console.log(`Drizzle schema check passed`)),c&&(console.log(`Seeding throwaway database`),await s(`default`,{cwd:e,env:r}),console.log(`Throwaway database seed check passed`))}finally{await f(t)}}async function f(e){await e.$client?.close?.(),await e.$client?.end?.()}export{u as checkSchemaPush};
@@ -1,4 +1,5 @@
1
1
  import { DatabaseDialect } from "./client.js";
2
+ import { PgAsyncDatabase } from "drizzle-orm/pg-core/async";
2
3
 
3
4
  //#region src/schema-push.d.ts
4
5
  type SchemaPushPlan = {
@@ -9,14 +10,30 @@ type SchemaPushPlan = {
9
10
  }>;
10
11
  apply(): Promise<void>;
11
12
  };
12
- type SchemaPushModule = {
13
- pushSchema(schema: Record<string, unknown>, db: never, migrationsConfig?: {
14
- table?: string;
15
- schema?: string;
16
- }): Promise<SchemaPushPlan>;
13
+ type DrizzleKitSqliteClient = {
14
+ query<Result = unknown>(sql: string, params?: unknown[]): Promise<Result[]>;
15
+ run(query: string): Promise<void>;
16
+ batch(statements: string[]): Promise<void>;
17
17
  };
18
- type ImportSchemaPushModule = (dialect: DatabaseDialect) => Promise<SchemaPushModule>;
18
+ type SchemaPushDatabase = {
19
+ postgres: PgAsyncDatabase<any>;
20
+ sqlite: DrizzleKitSqliteClient;
21
+ };
22
+ type MigrationsConfig = {
23
+ table?: string;
24
+ schema?: string;
25
+ };
26
+ type SchemaPushModules = {
27
+ postgres: {
28
+ pushSchema(schema: Record<string, unknown>, db: SchemaPushDatabase["postgres"], migrationsConfig?: MigrationsConfig): Promise<SchemaPushPlan>;
29
+ };
30
+ sqlite: {
31
+ pushSchema(schema: Record<string, unknown>, db: SchemaPushDatabase["sqlite"], migrationsConfig?: MigrationsConfig): Promise<SchemaPushPlan>;
32
+ };
33
+ };
34
+ type SchemaPushModule = SchemaPushModules[DatabaseDialect];
35
+ type ImportSchemaPushModule = <Dialect extends DatabaseDialect>(dialect: Dialect) => Promise<SchemaPushModules[Dialect]>;
19
36
  declare function planLocalSchemaPush(dialect: DatabaseDialect, schema: Record<string, unknown>, db: unknown, importModule?: ImportSchemaPushModule): Promise<SchemaPushPlan>;
20
37
  declare function inferSchemaDialect(schema: Record<string, unknown>): DatabaseDialect;
21
38
  //#endregion
22
- export { SchemaPushModule, SchemaPushPlan, inferSchemaDialect, planLocalSchemaPush };
39
+ export { SchemaPushDatabase, SchemaPushModule, SchemaPushPlan, inferSchemaDialect, planLocalSchemaPush };
@@ -1 +1 @@
1
- import{resolve as e}from"node:path";import{is as t}from"drizzle-orm";import{pathToFileURL as n}from"node:url";import{PgMaterializedView as r,PgTable as i,PgView as a}from"drizzle-orm/pg-core";import{SQLiteTable as o,SQLiteView as s}from"drizzle-orm/sqlite-core";import{resolve as c}from"import-meta-resolve";const l={postgres:`drizzle-kit/payload/postgres`,sqlite:`drizzle-kit/payload/sqlite`};async function u(e,t,n,r=f){let{pushSchema:i}=await r(e);return i(t,n)}function d(e){let t=!1,n=!1;for(let r of Object.values(e))t||=p(r),n||=m(r);if(t&&n)throw Error(`Local database schema mixes PostgreSQL and SQLite entities.`);if(t)return`postgres`;if(n)return`sqlite`;throw Error(`Could not infer local database dialect from src/db/schema.ts.`)}async function f(t){return await import(c(l[t],n(e(`package.json`)).href))}function p(e){return t(e,i)||t(e,a)||t(e,r)}function m(e){return t(e,o)||t(e,s)}export{d as inferSchemaDialect,u as planLocalSchemaPush};
1
+ import{resolve as e}from"node:path";import{is as t}from"drizzle-orm";import{pathToFileURL as n}from"node:url";import{PgMaterializedView as r,PgTable as i,PgView as a}from"drizzle-orm/pg-core";import{SQLiteTable as o,SQLiteView as s}from"drizzle-orm/sqlite-core";import{resolve as c}from"import-meta-resolve";const l={postgres:`drizzle-kit/payload/postgres`,sqlite:`drizzle-kit/payload/sqlite`};async function u(e,t,n,r=m){if(e===`postgres`){let{pushSchema:e}=await r(`postgres`);return e(t,n)}let{pushSchema:i}=await r(`sqlite`);return i(t,d(n))}function d(e){if(f(e))return e;let t=e?.$client??e;if(!t||typeof t.execute!=`function`)throw Error(`SQLite schema push requires a Drizzle database with a libSQL client or a native SQLite schema-push client.`);return{query:async(e,n=[])=>(await t.execute({sql:e,args:n})).rows,run:async e=>{await t.execute(e)},batch:async e=>{if(t.migrate){await t.migrate(e);return}if(t.batch){await t.batch(e);return}for(let n of e)await t.execute(n)}}}function f(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.query==`function`&&typeof t.run==`function`&&typeof t.batch==`function`}function p(e){let t=!1,n=!1;for(let r of Object.values(e))t||=h(r),n||=g(r);if(t&&n)throw Error(`Local database schema mixes PostgreSQL and SQLite entities.`);if(t)return`postgres`;if(n)return`sqlite`;throw Error(`Could not infer local database dialect from src/db/schema.ts.`)}async function m(t){return await import(c(l[t],n(e(`package.json`)).href))}function h(e){return t(e,i)||t(e,a)||t(e,r)}function g(e){return t(e,o)||t(e,s)}export{p as inferSchemaDialect,u as planLocalSchemaPush};
package/dist/seed.d.ts CHANGED
@@ -1,17 +1,24 @@
1
1
  import { SeedProfile } from "./config.js";
2
+ import { CoreframeConfig } from "@coreframe/config";
2
3
 
3
4
  //#region src/seed.d.ts
4
5
  type SeedLocalDbOptions = {
6
+ config?: CoreframeConfig;
7
+ cwd?: string;
5
8
  env?: NodeJS.ProcessEnv;
6
9
  };
7
10
  type RunProjectSeedOptions = {
11
+ cwd?: string;
8
12
  env: NodeJS.ProcessEnv;
9
13
  seedEntryPoint?: string;
10
14
  };
11
15
  declare function seedLocalDb(profile?: SeedProfile, {
16
+ config,
17
+ cwd,
12
18
  env
13
19
  }?: SeedLocalDbOptions): Promise<void>;
14
20
  declare function runProjectSeed(profile: SeedProfile | undefined, {
21
+ cwd,
15
22
  env,
16
23
  seedEntryPoint
17
24
  }: RunProjectSeedOptions): Promise<void>;
package/dist/seed.js CHANGED
@@ -1 +1 @@
1
- import{getSeedProfile as e}from"./config.js";import{startProjectPostgres as t}from"./local-postgres.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{importProjectModule as r,readProjectConfig as i}from"@coreframe/config";async function a(r=e(),{env:a=process.env}={}){try{var c=n();let e=await i(),l=s(e);await o(r,{env:c.a(await t({config:e,env:a,useSupervisorLease:!0})).env,seedEntryPoint:l}),console.log(`Seeded local database with "${r}" profile`)}catch(e){c.e=e}finally{await c.d()}}async function o(t=e(),{env:n,seedEntryPoint:a}){a??=s(await i()),await l(n,async()=>{await c(await r(a),a)({env:n,profile:t})})}function s(e){let t=e.database?.seed;if(!t)throw Error(`coreframe.config.ts must configure database.seed before running db seed.`);return t}function c(e,t){let n=e.default??e.seed??e.seedLocalDb;if(!n)throw Error(`${t} must export a default seed function, seed function, or seedLocalDb function.`);return n}async function l(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(t,process.env[t]),r===void 0?delete process.env[t]:process.env[t]=r;try{await t()}finally{for(let[e,t]of n)t===void 0?delete process.env[e]:process.env[e]=t}}export{o as runProjectSeed,a as seedLocalDb};
1
+ import{getSeedProfile as e}from"./config.js";import{startProjectPostgres as t}from"./local-postgres.js";import{startProjectTurso as n}from"./local-turso.js";import r from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{importProjectModule as i,readProjectConfig as a}from"@coreframe/config";async function o(i=e(),{config:o,cwd:l=process.cwd(),env:u=process.env}={}){try{var d=r();let e=o??await a({cwd:l}),p=c(e);if(e.database?.dialect===`sqlite`)try{var f=r();await s(i,{cwd:l,env:f.a(await n({config:e,cwd:l,env:u,useSupervisorLease:!0})).env,seedEntryPoint:p}),console.log(`Seeded local database with "${i}" profile`);return}catch(e){f.e=e}finally{await f.d()}await s(i,{cwd:l,env:d.a(await t({config:e,cwd:l,env:u,useSupervisorLease:!0})).env,seedEntryPoint:p}),console.log(`Seeded local database with "${i}" profile`)}catch(e){d.e=e}finally{await d.d()}}async function s(t=e(),{cwd:n=process.cwd(),env:r,seedEntryPoint:o}){o??=c(await a({cwd:n})),await u(r,async()=>{await l(await i(o,n),o)({env:r,profile:t})})}function c(e){let t=e.database?.seed;if(!t)throw Error(`coreframe.config.ts must configure database.seed before running db seed.`);return t}function l(e,t){let n=e.default??e.seed??e.seedLocalDb;if(!n)throw Error(`${t} must export a default seed function, seed function, or seedLocalDb function.`);return n}async function u(e,t){let n=new Map;for(let[t,r]of Object.entries(e))n.set(t,process.env[t]),r===void 0?delete process.env[t]:process.env[t]=r;try{await t()}finally{for(let[e,t]of n)t===void 0?delete process.env[e]:process.env[e]=t}}export{s as runProjectSeed,o as seedLocalDb};
package/dist/setup.d.ts CHANGED
@@ -1,10 +1,15 @@
1
1
  import { SeedProfile } from "./config.js";
2
+ import { CoreframeConfig } from "@coreframe/config";
2
3
 
3
4
  //#region src/setup.d.ts
4
5
  type SetupLocalDbOptions = {
6
+ config?: CoreframeConfig;
7
+ cwd?: string;
5
8
  env?: NodeJS.ProcessEnv;
6
9
  };
7
10
  declare function setupLocalDb(profile?: SeedProfile, {
11
+ config,
12
+ cwd,
8
13
  env
9
14
  }?: SetupLocalDbOptions): Promise<void>;
10
15
  //#endregion
package/dist/setup.js CHANGED
@@ -1 +1 @@
1
- import{startProjectPostgres as e}from"./local-postgres.js";import t from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{seedLocalDb as n}from"./seed.js";import{migrateLocalDb as r}from"./migrate.js";import{resetLocalDb as i}from"./reset.js";async function a(a=`default`,{env:o=process.env}={}){try{var s=t();let c=s.a(await e({env:o,useSupervisorLease:!0})).env;await i({env:c}),await r({env:c}),await n(a,{env:c})}catch(e){s.e=e}finally{await s.d()}}export{a as setupLocalDb};
1
+ import{startProjectPostgres as e}from"./local-postgres.js";import{startProjectTurso as t}from"./local-turso.js";import n from"./_virtual/_@oxc-project_runtime@0.138.0/helpers/esm/usingCtx.js";import{resetLocalDb as r}from"./reset.js";import{seedLocalDb as i}from"./seed.js";import{readProjectConfig as a}from"@coreframe/config";async function o(o=`default`,{config:s,cwd:c=process.cwd(),env:l=process.env}={}){try{var u=n();let d=s??await a({cwd:c}),f=d.database?.dialect===`sqlite`?t:e,p=u.a(await f({config:d,cwd:c,env:l,useSupervisorLease:!0})).env;await r({config:d,cwd:c,env:p}),await i(o,{config:d,cwd:c,env:p})}catch(e){u.e=e}finally{await u.d()}}export{o as setupLocalDb};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@coreframe/db",
3
- "version": "0.1.3",
4
- "description": "Database setup, migration, seeding, and local PostgreSQL utilities for Coreframe apps",
3
+ "version": "0.1.5",
4
+ "description": "Database setup, migration, seeding, and local PostgreSQL and SQLite/libSQL utilities for Coreframe apps",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/airlock-labs/coreframe.git",
@@ -22,10 +22,11 @@
22
22
  "import-meta-resolve": "^4.2.0",
23
23
  "local-postgres": "0.3.1",
24
24
  "nano-spawn": "^2.1.0",
25
- "@coreframe/config": "^0.1.3",
26
- "@coreframe/dev-supervisor": "^0.1.3"
25
+ "@coreframe/config": "^0.1.4",
26
+ "@coreframe/dev-supervisor": "^0.1.4"
27
27
  },
28
28
  "devDependencies": {
29
+ "@libsql/client": "^0.17.4",
29
30
  "@types/node": "^26.1.0",
30
31
  "tsdown": "0.22.3",
31
32
  "typescript": "6.0.3",